使用AsyncTask的响应作为回调

时间:2015-12-19 20:40:06

标签: java android android-asynctask

我希望能够在我调用onPostExecute()的类中的asynctask内调用一个方法 - 我该怎么做?

我的意思是,当我调用AsyncTask时:

public class MainActivity extends AppCompatActivity {

    public function onButtonClick() {
        String url = "http://sampledomain.pl/test.php";
        String params = "";
        new Api().execute(url, params);
    }

    public function changeText(String response)
    { 
        TextView txt = (TextView) findViewById(R.id.text);
        txt.setText(response);
    }

}

我希望能够像changeText这样的方法调用onPostExecute方法:

public class Api extends AsyncTask<String, Void, String> {
    // ...
    @Override
    public void onPostExecute(String response)
    {
        MainActivity obj = new MainActivity();
        obj.changeText(response);
    }

}

我在这里看到两个问题:

  1. 它不起作用,我不断收到java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.Window.findViewById(int)' on a null object reference错误

  2. 我希望这个类更通用,这意味着我想指定我想在MainActivity类中执行的方法,而不是Api类。

  3. 我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

首先,您应该创建一个回调接口。代码是通用的,您可以在应用程序的其他位置使用它。

public interface Callback<T>{
    void execute(T result);
}

然后您必须修改AsyncTask,以便接受Callback作为构造函数中的参数。

public class Api extends AsyncTask<String, Void, String> {
    public final Callback<String> callback;

    public Api(Callback callback) {
        this.callback = callback;
    }

    // other methods ...

    @Override
    public void onPostExecute(String response) {
        callback.execute(response);
    }
}

然后您可以将callback放入AsyncTask

public void onButtonClick() {
    String url = "http://sampledomain.pl/test.php";
    String params = "";
    new Api(new Callback<String>() {
        @Override
        public void execute(String result) {
            changeText(result);
        }
    }).execute(url, params);
}

答案 1 :(得分:0)

这是对您想要做的事情的可能解释。将对活动的引用传递给AsyncTask以及指定要调用哪个方法的枚举值。当在AsyncTask的MainActivity中执行这些方法时,请注意上下文不同 - 它们不在UI线程上。

public class MainActivity extends AppCompatActivity {

    ...

    doSomething(String response, MethodEnum method) {
        switch (method) {

            case ChangeText: changeText(response); break;

            case SomethingElse: somethingElse(response); break;

        }
    }
}

public class Api extends AsyncTask<String, Void, String, MainActivity, MethodEnum> {
    // ...
    // Main Activity is passed into doInBackground and set to a member 
    // variable there (mainAct), as is MethodEnum (method)

    @Override
    public void onPostExecute(String response) {
        mainAct.doSomething(response, method);
    }

}