使用AsyncTask创建回调函数

时间:2016-05-10 19:01:30

标签: java android

我已经创建了一个AsyncTask类来处理从我的服务器发送和接收。我正在尝试做的是在收到数据时触发事件或回调,这样我就可以使用所述数据来操作UI。

AsyncTask类:

public class DataCollectClass extends AsyncTask<Object, Void, JSONObject> {
    private JSONObject collected;

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

    //@Override -Commented out because it doesn't like the override
    protected void onPostExecute() {
        try {
            Log.d("Net", this.collected.getString("message"));
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected JSONObject doInBackground(Object... params) {
        OkHttpClient client = new OkHttpClient();

        // Get Parameters //
        String requestURI = (String) params[0];
        RequestBody formParameters = (RequestBody) params[1];
        Request request = new Request.Builder().url(requestURI).post(formParameters).build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // DO something on FAIL
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String jsonResponse = response.body().string();
                Log.d("Net", jsonResponse);
                try {
                    DataCollectClass.this.collected = new JSONObject(jsonResponse);
                    Log.d("Net", DataCollectClass.this.collected.getString("message"));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });

        return collected;
    }
}

这是有效的,它会将预期的JSON行打印到日志中。

它从Activity调用:

new DataCollectClass().execute(requestURI, formVars);

我看了一遍,似乎无法找到关于如何(以及在​​何处)添加回调的明确答案。优选地,回调代码本身应该与DataCollectClass一起使用,因此所有相关代码都可以在同一个地方重复使用。

有没有办法创建程序可以监听的自定义事件触发(类似于Javascript库)?

我一直把头发拉过来!

更新:

由于AsyncTask是多余的,我已将其删除并重写代码(以防其他人有同样的问题):

public class DataCollectClass {         私有JSONObject收集;

    public interface OnDataCollectedCallback {
        void onDataCollected(JSONObject data);
    }

    private OnDataCollectedCallback mCallback;

    public DataCollectClass(OnDataCollectedCallback callback, String requestURI, RequestBody formParameters){
        mCallback = callback;
        this.collect(requestURI, formParameters);
    }

    public JSONObject collect(String requestURI, RequestBody formParameters) {
        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder().url(requestURI).post(formParameters).build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //TODO Add what happens when shit fucks up...
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String jsonResponse = response.body().string();
                Log.d("Net", jsonResponse);
                try {
                    DataCollectClass.this.collected = new JSONObject(jsonResponse);

                    if(mCallback != null)
                        mCallback.onDataCollected(DataCollectClass.this.collected);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });
        return collected;
    }
}

来自活动:

new DataCollectClass(new DataCollectClass.OnDataCollectedCallback() {
    @Override
    public void onDataCollected(JSONObject data) {
        if(data != null) {
            try {
                // Do Something //
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
}, requestURI, formVars);

一切都完美! 谢谢!

3 个答案:

答案 0 :(得分:1)

如果您想利用AsyncTask的回调,可以通过以下方式处理它。

执行类似的操作(修改代码以添加以下内容)

public class DataCollectClass extends AsyncTask<Object, Void, JSONObject> {

    public interface OnDataCollectedCallback{
        void onDataCollected(JSONObject data);
    }

    private OnDataCollectedCallback mCallback;

    public DataCollectClass(OnDataCollectedCallback callback){
        mCallback = callback;
    }

    // your code that is already there
    ...

    @Override
    public onPostExecute(JSONObject response){
        if(mCallback != null)
            mCallback.onDataCollected(response);
    }
}

然后让魔术发生

new DataCollectClass(new OnDataCollectedCallback() {
        @Override
        public void onDataCollected(JSONObject data) {
            if(data != null)
                // DO something with your data
        }
    }).execute(requestURI, formVars);

但值得注意的是,most networking libraries, including OkHttp, handle background threads internally, and include callbacks to utilize with the requests.

这也实现了一个自定义接口,因此其他人可能会看到如何将它用于任何AsyncTask。

答案 1 :(得分:1)

有一个asynchronous get in OkHttp,所以你不需要AsyncTask,但作为一个学习练习,你可以将你的回调定义为一个类似的参数。

new DataCollectClass(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // DO something on FAIL
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                JSONObject collected = null;
                String jsonResponse = response.body().string();
                Log.d("Callback - Net", jsonResponse);
                try {
                    collected = new JSONObject(jsonResponse);
                    Log.d("Callback - Net", collected.getString("message"));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }).execute(requestURI, formVars);

AsyncTask

public class DataCollectClass extends AsyncTask<Object, Void, Call> {
    private Callback mCallback;
    private OkHttpClient client;

    public DataCollectClass(Callback callback) {
        this.mCallback = callback;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        this.client = new OkHttpClient();
    }

    @Override 
    protected void onPostExecute(Call response) {
        if (response != null && this.mCallback != null) {
            response.enqueue(this.mCallback);
        }
    }

    @Override
    protected Call doInBackground(Object... params) {

        // Get Parameters //
        String requestURI = (String) params[0];
        RequestBody formParameters = (RequestBody) params[1];
        Request request = new Request.Builder().url(requestURI).post(formParameters).build();

        return client.newCall(request); // returns to onPostExecute
    }
}

答案 2 :(得分:0)

使用asynctask调用Webservice是一种老式的。你可以使用Volley或改装。 但是您可以使用此过程来调用Webservice。以下是步骤:

  1. 创建一个接口并在您的Activity / Fragment

    中实现它
    public interface IAsynchronousTask {
            public void showProgressBar();
            public void hideProgressBar();
            public Object doInBackground();
            public void processDataAfterDownload(Object data);
     }
    
  2. 创建班级DownloadableAsyncTask。这堂课是:

    import android.os.AsyncTask;
    import android.util.Log;
    
    public class DownloadableAsyncTask extends AsyncTask<Void, Void, Object> {
    
        IAsynchronousTask asynchronousTask;
    
        public DownloadableAsyncTask(IAsynchronousTask activity) {
            this.asynchronousTask = activity;
        }
    
        @Override
        protected void onPreExecute() {
            if (asynchronousTask != null)
                asynchronousTask.showProgressBar();
        }
    
        @Override
        protected Object doInBackground(Void... params) {
            try {
                if (asynchronousTask != null) {
                    return asynchronousTask.doInBackground();
                }
            } catch (Exception ex) {
                Log.d("BSS", ex.getMessage()==null?"":ex.getMessage());
            }
            return null;
        }
    
        @Override
        protected void onPostExecute(Object result) {
            if (asynchronousTask != null) {
                asynchronousTask.hideProgressBar();
                asynchronousTask.processDataAfterDownload(result);
            }
        }
    
    }
    

    现在,在您的活动中,您将找到此方法。

    DownloadableAsyncTask downloadAsyncTask;
    ProgressDialog dialog;
        private void loadInformation() {
                if (downloadAsyncTask != null)
                    downloadAsyncTask.cancel(true);
                downloadAsyncTask = new DownloadableAsyncTask(this);
                downloadAsyncTask.execute();
    
            }
    
            @Override
            public void showProgressBar() {
                dialog = new ProgressDialog(this, ProgressDialog.THEME_HOLO_LIGHT);
                dialog.setMessage(" Plaese wait...");
                dialog.setCancelable(false);
                dialog.show();
    
            }
    
            @Override
            public void hideProgressBar() {
                dialog.dismiss();
    
            }
    
            @Override
            public Object doInBackground() {
                // Call your Web service and return value
    
            }
    
            @Override
            public void processDataAfterDownload(Object data) {
                if (data != null) {
                    // data is here
                }else{
                    //"Internal Server Error!!!"
                }
    
            }
    

    现在只需拨打loadInformation()方法,您就会在processDataAfterDownload()上收到回复。