【问题标题】:Android - Right design to implement AsyncTask or ThreadAndroid - 实现 AsyncTask 或 Thread 的正确设计
【发布时间】:2011-07-17 16:23:19
【问题描述】:

我有一个 getViewBitmap() 方法,它使用 3rd 方库(专有)创建位图,如下所示:

public Bitmap getViewBitmap(int index) {
    Bitmap retBitmap = null;

    int width = 400;
    int height = 200;

    try {
        retBitmap = lib.createBitmap(width, height, index);
    } catch(BMException e) {
        e.printStacktrace();
    }

    return retBitmap;
}

此方法用于在另一种方法中创建两个页面视图位图:

public Bitmap getTwoPageBitmap(int firstPageIndex, intSecondPageIndex) {
    Bitmap first = getViewBitmap(firstPageIndex);
    Bitmap second = getViewBitmap(secondPageIndex);

    Bitmap retBitmap = Bitmap.create(800, 400, first.getConfig());

    Canvas helperCanvas = new Canvas(splitViewBm);
    helperCanvas.drawBitmap(leftPageBitmap, 0, 0, null);
    helperCanvas.drawBitmap(rightPageBitmap, leftPageBitmap.getWidth(), 0, null);

    return retBitmap;
}

最后在启动方法中,我有这个:

public View createView() {
    MyView v = new MyView();
    if(pagePortratit) {
        v.setPageView(getViewBitmap(0));
    } else {
        // if page is landscape
        v.setPageView(getTwoPageBitmap(0, 1));
    }

    return v;
}

现在 - 我想让 getViewBitmap(int) 方法异步。由于“lib.createBitmap(int, int, int)”速度很慢并且会阻塞 UI,我希望在另一个线程中创建位图 (getViewBitmap(int))可能中断它的工作。

这种设计的正确设计是什么,以使实际上很重的方法异步?

【问题讨论】:

    标签: java android multithreading android-asynctask


    【解决方案1】:

    您可能希望继承 AsyncTask (read here) 并将您的 getBitmapView 代码放入 doInBackground() 方法 (@Override)。完成后,让onPostExecute() 方法更新视图/UI。确定横向或纵向的逻辑将希望在 AsyncTask 之外,并且您只想将任务外包给需要查看的任务(使用 .execute())。

    这可能是一种方法。

    【讨论】:

    • 好的 - 我明白这一点,但是 getTwoPageBitmap() 应该创建两个位图 - 因为任务是异步的 - 我怎么知道第一个是什么时候创建的,第二个是什么时候创建的,以便我合并它们合二为一?
    • 操作结束时会触发onPostExecute方法。对于每个,您可以在此处或其他地方包含一些逻辑以确定何时完成。查看这篇文章以了解更多信息(他们在这里也处理位图):http://developer.android.com/resources/articles/painless-threading.html
    • 是的 - 无论是一页还是两页视图,我都必须设置一些标志。非常感谢!还有一个 - 我将如何中断() AsyncTask。我知道有 .cancel(boolean) 方法——但这不会中断异步任务。我需要执行一次,如果另一个任务开始完成前一个任务,则中断它。
    • 好吧,IIRC,调用.cancel(true)会尝试中断线程来停止任务: > 如果任务已经开始,那么mayInterruptIfRunning参数决定了执行这个任务的线程是否应该被中断试图停止任务。在您的运行方法doInBackground(...) 中,您可以通过调用isCancelled() 检查它是否已被取消,并尝试更快地停止它。看到这个:[AsyncTask#cancel(boolean)] (developer.android.com/reference/android/os/…) 我认为这解决了你的问题。
    • 杰克:非常感谢您的帮助!愿托尔保佑你。谢谢
    【解决方案2】:

    我认为您能做的最好的事情是使用AysncTask,它允许您直接更新 UI,而无需对 UI 线程更新进行特殊处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-13
      • 1970-01-01
      • 2014-10-11
      相关资源
      最近更新 更多