可以在AsyncTask中重载publishProgress吗?

时间:2014-04-23 17:28:52

标签: android android-asynctask

我正在尝试在后台进程中发布两种不同的进度。我试图在某个时间发布一个字符串,并在另一个时间发布一个整数。我通过重载它来处理onProgressUpdate中的两种参数。但是当我声明我的AsyncTask类时,我有一些参数,这就是为什么它期望我只发送字符串类型的参数。有没有办法处理这两种类型的publishProgress事件?

1 个答案:

答案 0 :(得分:3)

基本上有两种方法可以解决您的问题:

第一个非常简单,你总是publishUpdate(String),然后在你的onProgressUpdate(String)中检查字符串是int还是字符串,并以不同的方式处理每个案例:

private class MyAsyncTask extends AsyncTask<Void, String, Void> {
    //Executed on main UI thread.
    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values); 
        try{
            Integer i = Integer.parseInt(values[0]);
            TextView v1 = (TextView) findViewById(R.id.textView1);
            v1.setText(String.valueOf(i));
        }
        catch(NumberFormatException e){
            TextView v2 = (TextView) findViewById(R.id.textView3);
            v2.setText(values[0]);
        }
    }
    @Override
    protected Void doInBackground(Void... params) {
        int i = 0;
        while(i < 100){
            try {
                if(i%2 == 0){
                    publishProgress("Divisible by 2: " + String.valueOf(i));
                }
                publishProgress(String.valueOf(i));
                i++;
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }   
        return null;
    }
}

在上面的示例中,我只是尝试将字符串解析为Integer - 如果它有效,那么我100%确定它是一个int - 如果它抛出异常则它是String

如果您想要更多控制,则需要实现自己的AsyncTask版本,该版本支持一个或多个进度更新。实现此目的的唯一方法是直接使用Handlershttp://developer.android.com/reference/android/os/Handler.html)和Threadhttp://developer.android.com/reference/java/lang/Thread.html)(最好包含在类似于AsyncTask的更逻辑的类中):< / p>

import android.os.Handler;
import android.os.Looper;

public abstract class DIYAsyncTask<Params, IntProgress, StringProgress, Result> {

    private Result backGroundResult;

    //Run on UI thread
    @SuppressWarnings("unchecked")
    protected void execute(Params... params){
        final Params[] thisParams = params;
        Thread worker = new Thread(){
            public void run(){
                prepareForPreExecute();
                backGroundResult = doInBackground(thisParams);
                prepareForPostExecute();
            }
        };
        worker.setPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
        worker.start();
    }

    //Code to start onPreExecute on UI thread
    private void prepareForPreExecute(){
        Handler ui_handler = new Handler(Looper.getMainLooper());
        ui_handler.post(
                new Runnable(){
                    public void run(){
                        onPreExecute();
                    }
                }
            );
    }

    //Code to start onPostExecute on UI thread
    private void prepareForPostExecute(){
        Handler ui_handler = new Handler(Looper.getMainLooper());
        ui_handler.post(
                new Runnable(){
                    public void run(){
                        onPostExecute(backGroundResult);
                    }
                }
            );
    }

    //Always run on worker thread
    @SuppressWarnings("unchecked")
    protected abstract Result doInBackground(Params... params);

    //Always run on UI
    protected void onPreExecute(){
    }

    //Always run on UI
    protected void onPostExecute(Result result){
    }

    //Run on worker
    @SuppressWarnings("unchecked")
    protected void publishIntProgress(IntProgress... values){
        Handler ui_handler = new Handler(Looper.getMainLooper());
        final IntProgress[] thisProgress = values;
        ui_handler.post(
                new Runnable(){
                    @Override
                    public void run(){
                        onIntProgressUpdate(thisProgress);
                    }
                }
        );
    }

    //Always run on UI
    @SuppressWarnings("unchecked")
    protected void onIntProgressUpdate(IntProgress... values){

    }

    //Run on worker
    @SuppressWarnings("unchecked")
    protected void publishStringProgress(StringProgress... values){
        Handler ui_handler = new Handler(Looper.getMainLooper());
        final StringProgress[] thisProgress = values;
        ui_handler.post(
                new Runnable(){
                    @Override
                    public void run(){
                        onStringProgressUpdate(thisProgress);
                    }
                }
        );
    }

    //Always run on UI
    @SuppressWarnings("unchecked")
    protected void onStringProgressUpdate(StringProgress... values){

    }
}

然后你可以像这样覆盖(注意与使用AsyncTask的相似性)

private class MyDIYAsyncTask extends DIYAsyncTask<Void, Integer, String, Void> {

    //Executed on main UI thread.
    @Override
    protected void onIntProgressUpdate(Integer... values) {
        super.onIntProgressUpdate(values); 
        TextView v = (TextView) findViewById(R.id.textView1);
        v.setText(String.valueOf(values[0]));
    }

    @Override
    protected void onStringProgressUpdate(String... values) {
        super.onStringProgressUpdate(values);
        TextView v = (TextView) findViewById(R.id.textView3);
        v.setText(values[0]);
    }

    @Override
    protected Void doInBackground(Void... params) {

        int i = 0;
        while(i < 100){
            try {
                publishIntProgress(i);
                publishStringProgress("MyString" + String.valueOf(i));
                i++;
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

}