4

I edited my code according dear Mayank'answer but It does not show any message that is sended as input in displayMsg() method before method begines..I should say MethodTest() is started with nfc and in method onNewIntent(Intent intent)

@Override
protected void onNewIntent(Intent intent) {
   MethodTest();
    ..............

}

public void MethodTest() {
    DisplayMsg("method 1 is running");
    Method1();

    DisplayMsg("method 2 is running");
    Method2();

    DisplayMsg("method 3 is running");
    Method3();

}

private int DisplayMsg(String msg) {
    totalMsg += msg;
    DisplayMsgClass dc = new DisplayMsgClass();
    dc.doInBackground(totalMsg);
}

private class DisplayMsgClass extends AsyncTask<String, Integer, String> {

    @Override
    protected void onPreExecute() {
         textView.setText("Hello !!!");
        progressBar = (ProgressBar) findViewById(R.id.progressBar1);
        progressBar.setVisibility(View.VISIBLE);
        super.onPreExecute();
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);

    }

    @Override
    protected String doInBackground(String... Messages) {


        return Messages[0];
    }

    @Override
    protected void onPostExecute(String result) {
        progressBar.setVisibility(View.INVISIBLE);

        textView.setText(result);
    }
}

in my layout:

<LinearLayout>
<ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:visibility="gone"
    android:id="@+id/progressBar1"
    />
 <TextView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:id="@+id/textv1"
  android:hint="AppletPass"
  android:gravity="center"/>
 </LinearLayout>
Fatemeh
  • 177
  • 15
  • 3
    What do you mean by `int value= obj.doInBackground(msg);` ? See [AsyncTask](https://developer.android.com/reference/android/os/AsyncTask.html) for proper AsyncTask implementation – ρяσѕρєя K Nov 08 '16 at 08:27
  • It is not important.I put it for make sure that DisplayMsg is executed and create a time for can see dialog – Fatemeh Nov 08 '16 at 08:29
  • 5
    Ok, use `obj.execute("");` instead of `int value= obj.doInBackground(msg);` and check `ProgressDialog` is showing or not – ρяσѕρєя K Nov 08 '16 at 08:31
  • if you want to wait till async task is executed add .get while calling async task but it is not recommended as Ui will freeze until the results are got – Manohar Nov 08 '16 at 08:35
  • obj.execute("") not working. I put breakpoin on "onProgressUpdate" but I see when Method1() is finished ,onProgressUpdate is called. why? – Fatemeh Nov 08 '16 at 08:39
  • I have this problem for some days. please help me or give me a solution for show message instead progress dialog – Fatemeh Nov 08 '16 at 09:05
  • @Fatemeh What do you mean that you need to show a message instead of a progress dialog? A progress dialog is what contains a message in your code already. – Malcolm Nov 08 '16 at 09:06
  • I only need show step messages while MethodTest is runnig.if progress dialog is not good please give me another solution – Fatemeh Nov 08 '16 at 09:12
  • Can you please elaborate completely what do you want to achieve?? If you just want to set resultin a textView from onPostEexecute than it can be done by this. String result = new DisplayMsgClass().execute(totalMsg).get(); textView.setText(result); – Hobbit Nov 26 '16 at 08:57

4 Answers4

3

Remember that AsyncTasks should ideally be used for short operations (a few seconds at the most.)

Try to learn more about AsyncTask and there are so many mistakes in your code

  1. Do not call doInBackground() manually.

    dc.doInBackground(totalMsg); // Error

  2. DisplayMsg() called several times, each time a new instance of class DisplayMsgClass created

    DisplayMsgClass dc = new DisplayMsgClass(); // Error

  3. onPreExecute()
    textView.setText("Hello !!!"); // NullPointerException. textView.setText() is called without initializing it.

Caution

Do not call AsyncTask.execute() more than one on a same intance.
For eg:

DisplayMsgClass displayMsgClass = new DisplayMsgClass();  
displayMsgClass.execute();  
displayMsgClass.execute(); //Error, IllegalStateException  

will show you a basic demo based on you implementation and you can simply modify it according to your own way.

public void MethodTest() {

    // execute task
    new DisplayMsgClass().execute("Download now");
}

/*
public void MethodTest() {
    DisplayMsg("method 1 is running");
    Method1();

    DisplayMsg("method 2 is running");
    Method2();

    DisplayMsg("method 3 is running");
    Method3();

}

private int DisplayMsg(String msg) {
    totalMsg += msg;
    DisplayMsgClass dc = new DisplayMsgClass();
    dc.doInBackground(totalMsg);
}
*/

private class DisplayMsgClass extends AsyncTask<String, Integer, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        // retrieve the widgets
        progressBar = (ProgressBar) findViewById(R.id.progressBar1);
        textView = (TextView) findViewById(R.id.textv1);


        textView.setText("Download initialized");
        progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
    }

    @Override
    protected String doInBackground(String... Messages) {

        // read commands
        String command = Messages[0];
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Download completed";
    }

    @Override
    protected void onPostExecute(String result) {

        //invoked on the UI thread after the background computation finishes
        progressBar.setVisibility(View.INVISIBLE);
        textView.setText(result);
    }
} 
Mable John
  • 4,518
  • 3
  • 22
  • 35
2

The reason why you are seeing onProgressUpdate(Progress...) called at the end of if(...) is because publishProgress(Progress... values) posts a message to an internal handler, this internal handler later processes the message to update the progress. In other words, publishProgress(Progress... values) doesn't synchronously call onProgressUpdate(Progress...) See implementation here: https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/AsyncTask.java#L649

This is necessary because publishProgress(Progress... values) is expected to be called from doInBackground(Params...), which is on the worker thread for an AsyncTask, whereas onProgressUpdate(Progress...) happens on the UI thread so the UI can reflect the progress change. By posting a message to the handler on the UI thread, the progress info can be synced from worker thread to the UI thread without blocking either thread.

Doris Liu
  • 807
  • 5
  • 9
  • Thank you for answer me. wxcuse me I don't understand.Should I call onProgressUpdate(Progress...) in doInBackground(Params...) instead publishProgress(Progress... values)? can you give me code changes? – Fatemeh Nov 23 '16 at 16:38
  • It's unclear to me why you choose to use AsyncTask: AsyncTask is designed for expensive background tasks that run on a worker thread to free UI thread from doing time-consuming tasks that potentially cause frame dropping. Is `MethodTest()` supposed to run on the UI thread or a background thread? – Doris Liu Nov 23 '16 at 19:54
  • 1
    I use nfc. It calls new intent method and in this method i call method test. I could 't find any solution and used async task. If you have a solution for my problem please give me. I only want to show message before call a method – Fatemeh Nov 24 '16 at 06:31
  • I believe `onNewIntent(Intent)` is called on the UI thread, which means you can modify TextView directly in that method instead of using an AsyncTask. – Doris Liu Nov 24 '16 at 06:48
  • I edited my code private void DisplayMsg(String msg) { totalMsg +=msg; textv.setText(msg); } in debug mode i get txtv.gettesxt() ,text view has new message but on ui It does not show new message. and it's message not changed – Fatemeh Nov 24 '16 at 07:09
  • That is because any change to a View (including TextView) would cause the View to be marked dirty and the new content will be reflected/drawn on the screen after the next draw pass (which happens every 16ms). Your breakpoint is set before the next draw pass happens. – Doris Liu Nov 24 '16 at 07:20
  • yest at the end of method textview content is changed. what can i do for change content at the run time? I edited it as textv.setText(totalMsg) – Fatemeh Nov 24 '16 at 07:32
  • If you mean change content on **screen** at the time of calling the setText(...), that is not possible. Basically you'll have to wait until the screen refreshes again (at 60Hz frequency) to see the new content. In reality, you wouldn't notice it's not instantaneous, just like in games when you move a character with your controller, you won't see them move until the TV refreshes (also mostly at 60Hz), but you won't notice the lag. – Doris Liu Nov 24 '16 at 07:51
  • can i use progress bar? and set changed text on it? – Fatemeh Nov 24 '16 at 08:06
  • You can use a progress bar with a TextView to reflect text change, of course. Progress bar itself doesn't manage text. See: https://developer.android.com/reference/android/widget/ProgressBar.html – Doris Liu Nov 24 '16 at 08:13
1

Try below code

private int DisplayMsg(String msg) {
    totalMsg += msg;
    DisplayMsgClass dc = new DisplayMsgClass();
    dc.runner.execute(totalMsg);
}

Hope it will work

:)GlbMP

  • Excuse me but runner in dc is undefined. I wrote dc.onPostExecute(totalMsg); but when textv.setText(result); is executed in method onPostExecute(String result) textview content not changed :( why progress bar is needed? what does it do? – Fatemeh Nov 24 '16 at 16:08
0

create progress bar in xml layout and set its visibility gone by default and create code as sample

// AsyncTask .

    private class DownloadWebPageTask extends AsyncTask<String, Integer, String> {

    @Override
    protected void onPreExecute() {
        //textView.setText("Hello !!!");
        progressBar = (ProgressBar) findViewById(R.id.progressBar1);
        progressBar.setVisibility(View.VISIBLE);
        super.onPreExecute();
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);

    }

    @Override
    protected String doInBackground(String... urls) {
        String response = "";
        for (String url : urls) {
            DefaultHttpClient client = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            try {
                HttpResponse execute = client.execute(httpGet);
                InputStream content = execute.getEntity().getContent();

                BufferedReader buffer = new BufferedReader(new InputStreamReader(
                        content));
                String s = "";
                while ((s = buffer.readLine()) != null) {
                    response += s;
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return response;
    }

    @Override
    protected void onPostExecute(String result) {
        progressBar.setVisibility(View.INVISIBLE);
        textView.setText(result);
    }
}
Mayank Sharma
  • 2,735
  • 21
  • 26
  • Thank you for answer me. Excuse me what is textview?why is it used? I edited my code acorrding your post. but not show any message again – Fatemeh Nov 23 '16 at 17:01
  • its an example , so basically in that example we get data from server ( in json ) and show it into Textview . you have to modify it according to your requirement – Mayank Sharma Nov 24 '16 at 05:40
  • I edited my code. I put text view and I put my edited code in question again. after call dc.doInBackground(totalMsg); in displaymsg() method. only doInBackground is called and return and nothing show in text view. should not i call publishProgress in doInBackground method? – Fatemeh Nov 24 '16 at 06:07
  • i load ui and then create a new intent and call MethodTest(). can I change textview'value in this new intent? – Fatemeh Nov 24 '16 at 06:27