从AsyncTask类回调

时间:2014-07-12 15:35:25

标签: java android android-asynctask asynccallback

我有 APIHelper 类,其静态方法异步向服务器发出请求,接收json字符串,解析并返回Object或ArrayList:

    ...
public static ArrayList<Item> getItemsInCategory(int id_category) throws ExecutionException, InterruptedException, JSONException {
        DoRequest doRequest = new DoRequest();
        String jsonString = doRequest.execute(API_PATH + PRODUCT_SEARCH + CATEGORY_ID + id_category).get();
        JSONObject jsonObject = new JSONObject(jsonString);
        JSONArray jsonArray = jsonObject.getJSONArray("products");
        return Item.fromJson(jsonArray);
        }
public static Item getItem(int id_item) throws ExecutionException, InterruptedException, JSONException {
        DoRequest doRequest = new DoRequest();
        String jsonString = doRequest.execute(API_PATH + PRODUCT_GET_INFO + id_item).get();
        JSONObject jsonObject = new JSONObject(jsonString);
        return Item.fromJson(jsonObject);
        }
    ...

现在我想在不从AsyncTask类 DoRequest 调用 get()方法的情况下创建方法。

我的 DoRequest 类:

public class DoRequest extends AsyncTask<String, Void, String> {
    ResultListener mResultListener;

    public abstract interface ResultListener{
        Object onResultAvailable(String result) throws JSONException;
    }

    DoRequest(ResultListener resultListener){
        mResultListener = resultListener;
    }


    @Override
    protected String doInBackground(String... URL) {
        ServiceHandler serviceHandler = new ServiceHandler();
        String jsonStr = serviceHandler.makeServiceCall(URL[0]);
        return jsonStr;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        try {
            mResultListener.onResultAvailable(result);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

帮助我改变APIHelper类中的方法,它们在从DoRequest回调后返回值。

1 个答案:

答案 0 :(得分:2)

您可以使用像otto这样的事件总线让异步任务在onPostExecute中将事件发布到事件总线一次,然后让Helper类将其结果返回给谁,监听总线上的事件然后处理那里的回调。

http://square.github.io/otto/

使用它的一个例子是:

首先,您必须使用自定义post方法才能从后台发布到线程。

public class MainThreadBus extends Bus {
    private final Handler handler = new Handler(Looper.getMainLooper());

    @Override public void post(final Object event) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            super.post(event);
        } else {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    post(event);
                }
            });
        }
    }
}

现在我们有了这个设置,在调用helper类的类中,我们在总线上创建一个寄存器并调用helper方法:

class someClass(){
    ///some stuff
    public void performRestCall(int id_category){
    bus.register(this);
    ApiHelper.getItemsInCategory(id_category);
    }

    @Subscribe
    public void restCallCompleted(GetCategoryEvent e){
    ArrayList<Item> list = e.getList();
    //do whatever else you need to
    bus.unRegister(this);
    }
}

现在在asyncTask onPostExecute中,我们执行asyncTask完成后我们正在做的所有工作,并告诉总线上的每个人这个事件已经完成。我们传递对象中的列表,而不是从方法返回它。:

 @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        bus.register(this);
        try {
             JSONObject jsonObject = new JSONObject(jsonString);
             bus.post(new GetCategoryEvent( Item.fromJson(jsonObject));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

你的解决方案将最终成为这些方面的东西。