首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >小型安卓AsyncTask项目

小型安卓AsyncTask项目
EN

Code Review用户
提问于 2012-05-13 07:05:26
回答 3查看 7.3K关注 0票数 2

我用AsyncTask创建了一个小型安卓项目。它模拟一个耗时的任务。

请检查我的代码,并告诉我,你会以不同的方式做什么,以及为什么。欢迎评论,不特定于Android,而是一般的软件开发。

CounterTask.java:

代码语言:javascript
复制
package my.tasks;

import java.util.Random;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.util.Log;

/**
 * @author 2
 * 
 *         Simulates a time consuming task, counts in the background from 0 to
 *         the given value in first parameter. Its progress is published via an
 *         integer which is a percentual value 0..100. The task may not
 *         complete, it may fail or it may be cancelled by the user. In case of
 *         success it returns true.
 */
public class CounterTask extends AsyncTask<Integer, Integer, Boolean> {

    private static final long DELAY = 100;
    private static final int PROBABILITY_TO_FAIL_EVERY_STEP = 1;
    private static final String TAG = "CounterTask";
    private ProgressDialog progressDialog;
    private Random random;

    /**
    * @param progressDialog
    * a ProgressDialog the task can use to display its progress.
    */
    public CounterTask(ProgressDialog progressDialog) {
        this.progressDialog = progressDialog;
        this.progressDialog.setMax(100);
        this.random = new Random();
    }

    /*
    * (non-Javadoc)
    * 
    * @see android.os.AsyncTask#doInBackground(Params[])
    * 
    * Set params[0] to the maximum value you want the task to count to.
    */
    @Override
    protected Boolean doInBackground(Integer... params) {
        validateParams(params);
        int count_max = params[0];

        for (int i = 0; i < count_max; i++) {
            int progressPercent = calculateProgressPercent(i, count_max);
            publishProgress(progressPercent);
            Log.i(TAG, "Counter: " + Integer.toString(i));
            Log.i(TAG, "Progress published: " + Integer.toString(progressPercent) + "%");
            if (sleep() == false) {
                return false;
            }
            if (doesFail(PROBABILITY_TO_FAIL_EVERY_STEP)) {
                Log.i(TAG, "Background fails.");
                return false;
            }
        }

        Log.i(TAG, "Background succeeds.");
        return true;
    }

    @Override
    protected void onCancelled() {
        super.onCancelled();
        Log.i(TAG, "Background cancelled.");
    }

    @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
        progressDialog.dismiss();

        String message = null;
        if (result)
            message = "Background succeeded.";
        else
            message = "Background failed.";
        Log.i(TAG, message);
        createAlertDialog(message).show();
    }

    private Dialog createAlertDialog(String message) {
        AlertDialog.Builder builder = new Builder(progressDialog.getContext());
        AlertDialog dialog = builder.setMessage(message).setTitle("Result").setCancelable(true).create();
        return dialog;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        progressDialog.setProgress(values[0]);
    }

    /**
    * Helper method to decide if the task fails in this step.
    * 
    * @param probabilityToFail
    *            Value 0..100 the probability to fail.
    * @return true if it fails, false if not
    */
    private boolean doesFail(int probabilityToFail) {

        int prob = random.nextInt(100);
        if (prob < probabilityToFail)
            return true;
        else
            return false;
    }

    /**
    * The thread sleeps from step to step to simulate a time consuming task.
    * 
    * @return
    */
    private boolean sleep() {
        try {
            Thread.sleep(DELAY);
        } catch (InterruptedException e) {
            return false;
        }
        return true;
    }

    private int calculateProgressPercent(int done, int max) {
        done = done * 100;
        return done / max;
    }

    private void validateParams(Integer... integers) {
        if (integers == null || integers.length != 1 || integers[0] < 0)
        throw new IllegalArgumentException();
    }
}

MainActivity.java:

代码语言:javascript
复制
package my.application;

import my.tasks.CounterTask;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener, OnCancelListener {
    private CounterTask counterTask;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button startButton = (Button) findViewById(R.id.startButton);
        startButton.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        int id = view.getId();

        switch (id) {
        case R.id.startButton:
            ProgressDialog progressDialog = createProgressDialog();
            progressDialog.show();
            CounterTask ct = new CounterTask(progressDialog);
            counterTask = (CounterTask) ct.execute(100);
            break;

        default:
            break;
        }
    }

    private ProgressDialog createProgressDialog() {

        ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setProgress(0);
        progressDialog.setMax(100);
        progressDialog.setTitle("Progress");
        progressDialog.setCancelable(true);
        progressDialog.setOnCancelListener(this);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        return progressDialog;
    }

    @Override
    public void onCancel(DialogInterface arg0) {
        counterTask.cancel(true);
    }
}
EN

回答 3

Code Review用户

发布于 2012-05-15 00:12:16

看起来不错。您可以将progressDialog创建并显示在onPreExecute:http://developer.android.com/reference/android/os/AsyncTask.html#onPreExecute()http://developer.android.com/reference/android/os/AsyncTask.html#onPreExecute()中。它将在UI线程中运行,并封装更多的对话逻辑。

你可以在这里删掉几行

代码语言:javascript
复制
String message = null;
if (result)
    message = "Background succeeded.";
else
    message = "Background failed.";

变成了

代码语言:javascript
复制
String message = result ? "Background succeeded." : "Background failed";
票数 3
EN

Code Review用户

发布于 2014-04-01 07:38:25

条件运算符可用于改进以下方法:

代码语言:javascript
复制
private boolean doesFail(int probabilityToFail) {

    int prob = random.nextInt(100);
    if (prob < probabilityToFail)
        return true;
    else
        return false;
}

可以改进为

代码语言:javascript
复制
private boolean doesFail(int probabilityToFail) {
    return (random.nextInt(100) < probabilityToFail);
}
票数 1
EN

Code Review用户

发布于 2015-07-02 09:30:36

  • 不要在构造函数中将ProgressDialog作为参数传递(当活动被重新创建并且任务仍在运行或完成时会发生什么?)了解更多关于序列化的信息。
  • 如果在引用字段时不调用涉及创建对象的其他构造函数或将其用作限定符,则不要在构造函数中使用此关键字。
  • 使用onPreExecute()来显示ProgressDialog如下:@重载受保护的ProgressDialog onPreExecute() { /**显示进度对话框*/ showProgressDialog(_context,_message);} /**显示pd方法*/私有(上下文、字符串消息){ /**检查是否还没有创建进度对话框或上下文没有更改-例如。在屏幕旋转期间*/ if(_progressDialog == null _progressDialog.getContext().equals(上下文)){ /**创建进度对话框*/ _progressDialog =新的ProgressDialog(上下文);_progressDialog.setCancelable(false);} /** set消息*/ _progressDialog.setMessage(消息);/**显示pd */ _progressDialog.show();}
  • 始终找出您的任务可能被您或其他因素终止的位置,并尝试关闭进度对话框私有无效dismissProgressDialog() { try { /**检查如果进度对话框正在显示*/ if (_progressDialog != null & _progressDialog.isShowing()) { /**解散登录对话框*/ _progressDialog.dismiss();}(异常e) { //句柄或日志或忽略}最后{ _progressDialog = null;}
    • onPostExecute您应该关闭进度对话框而不是显示它
    • 要显示结果,请创建对活动的回调

定义接口:

代码语言:javascript
复制
public interface AsyncTaskResultListener<T> {

    /**  notifies Activity when task is done.
     *   @return true if result parsed OK
     *   other way false to repeat with RepeatTask()*/
    boolean onTaskComplete(T result);
    void repeatTask();
}

在异步任务中:

代码语言:javascript
复制
    AsyncTaskResultListener<T> _callback;
    Context _context;

    MyAsyncTask(Context context) {
       /** check for valid context */
        if(Activity.class.isAssignableFrom(context.getClass()) {
            _contex = context;
            /** check for valid callback */
             if(AsyncTaskResultListener.class.isAssignableFrom(context.getClass()) {
                 /** cast it to interface */
                 _callback = (AsyncTaskResultListener<T>) context;
            }
        }
    }

    @Override
    protected void onPostExecute(T result) {
       if(_callback!=null) {
            if(!callback.onTaskComplete(result) {
                /** repeat task */
                callback.repeatTask()
            }
        }
        /** dismiss pd */
    }

在活动中:

代码语言:javascript
复制
public MyActivity exrtends Activity implements AsyncTaskResultListener<T> {

    @Override 
    boolean onTaskComplete(T result) {
        /** do work with your result 
        if satisfied return true, to repeat task return false */
        return true;
    }

    @Override
    public void repeatTask() {
        /** free to make decision what to do */
    }
}

我没有什么要指出的,但我的手已经够多了

票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/11730

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档