【问题标题】:Callback from AsyncTask class来自 AsyncTask 类的回调
【发布时间】:2014-09-03 01:38:06
【问题描述】:

我有 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 回调后返回值。

【问题讨论】:

    标签: java android android-asynctask asynccallback


    【解决方案1】:

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

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

    使用它的一个例子是:

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

    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);
                    }
                });
            }
        }
    }
    

    现在我们已经设置好了,在调用辅助类的类内部,我们在总线上创建一个寄存器并调用辅助方法:

    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();
            }
        }
    

    你的解决方案最终会是这样的。

    【讨论】:

    • 请写一个例子。
    • @user3284037。我写了一个简单的小例子,这应该有助于解释你如何使用它以及如何在课堂上实际使用它。
    • 请记住,当您使用 @Subscribe 注释时,请确保您导入 otto 注释,而不是用于 google bus 的注释。使用 IDE 尝试自动导入依赖项时,这是一个非常容易犯的错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    • 2017-07-05
    • 1970-01-01
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多