简体   繁体   中英

How to update UI on external asynctask on android

MainActivity execute external asynctask class

Here my code

public class MainActivity extends AppCompatActivity implements View.OnClickListener
...
public void onFirstBtnClick()
{
    AysncClass ac = new AyncClass();
    ac.execute();
}

and external asynctask

public class AysncClass extends AsyncTask<String, String, Integer>

    @Override
    protected Integer doInBackground(String... strings) {
        Method1(strings[0], Integer.parseInt(strings[1]));
        return null;
    }

    public Method1(Strins s, int i)
    {
        onProgressUpdate("first start");
        publishProgress();
        // do more work
        onProgressUpdate("second start");
        publishProgress();
    }

    public void Method2()
    {
        onProgressUpdate("Method2 here");
        publishProgress();
    }
    ...
     @Override
    protected void onProgressUpdate(final String... values) {
    super.onProgressUpdate(values);
    // what can i do here?
    }
}

I use runOnUiThread like this in onProgressUpdate

    ((MainActivity)context).runOnUiThread(new Runnable()
    {
        @Override
        public void run()
        {
            ((MainActivity)context).tvRead.append(values[0]);
        }
    });*

but It occur 'java.lang.ArrayIndexOutOfBoundsException: length=0; index=0' even though values[0] is not null.

Also I use interface

this.context.WriteText(values[0]);

It occur same error

And I do this...

((MainActivity)context).tvRead.append(values[0]);

It occur 'java.lang.RuntimeException: An error occured while executing doInBackground()' and 'CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.'

...How can I resolve?

Do not call onProgressUpdate() . Instead just call publishProgress("The String") .

By calling publishProgress without a parameter you will have no values in onProgressUpdate . That's why you get an IndexOutOfBondException.

Don't call onProgressUpdate on your own. Call publishProgress("My Message");

In onProgressUpdate, don't use runOnUIThread.

OnProgressUpdate runs on the Ui thread only.

Instead of this

onProgressUpdate("Method2 here");
publishProgress();

Do this

publishProgress("Method2 here");

On ProgressUpdate will be in UIThread, no need again specify in UI thread. From DoInbackGround you have to make call publishProgress method for invoking OnProgressUpdate.

Use an interface as communicator between your Activity and AsyncTask

Create Interface

interface MyInterface {
    void callActivityUi(String progress);  // use float maybe
}

Initialize AsyncTask like this:

AysncClass as = new AysncClass(new MyInterface() {
    @Override
    void callActivityUi (String progress) {
        // you will receive data here
    }

});

Create a constructor in your AysncClass

private MyInterface myInterface;
public AysncClass (MyInterface myInterface) {
    this.myInterface = myInterface;
}

Call Activity in onProgressUpdate(String... values)

myInterface.callActivityUi(values[0]);

Based on your code, you can use an interface to post the progress to the activity. I modified your code like this:

AsyncTask class

public class AysncClass extends AsyncTask<String, String, Integer> {

    public interface SomeListener {
        public void onSomething(Object mObject);
    }

    private SomeListener sl;

    public AysncClass(SomeListener sl) {
        this.sl = sl;
    }

    @Override
    protected Integer doInBackground(String... strings) {
        Method1(strings[0], Integer.parseInt(strings[1]));
        return null;
    }

    public Method1(Strins s, int i) {
        onProgressUpdate("first start");
        publishProgress();
        // do more work
        onProgressUpdate("second start");
        publishProgress();
    }

    public void Method2() {
        onProgressUpdate("Method2 here");
        publishProgress();
    }
    ...
    @Override
    protected void onProgressUpdate(final String... values) {
        super.onProgressUpdate(values);
        // what can i do here?
        sl.onSomething(mObject);
    }
}

MainActivity class

public class MainActivity extends AppCompatActivity implements View.OnClickListener,
    AysncClass.SomeListener {
    ...
    public void onFirstBtnClick() {
        AysncClass ac = new AyncClass(this);
        ac.execute();
    }

    @Override
    public void onSomething(Object mObject) {
        //Do your UI work here
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM