【问题标题】:AsyncTask does not seem to work really asyncAsyncTask 似乎并没有真正异步工作
【发布时间】:2012-03-28 15:41:37
【问题描述】:

我正在调用 AsyncTask 来停止以前启动的服务。 但是当 Asyctask 运行时 ProgressDialog 不会旋转。 所以我认为有问题,我可能会遇到 ANR 错误的问题。

有什么想法吗?

new asyncTaskZieladresse().execute();

public class asyncTaskZieladresse extends AsyncTask<Void, Integer, Void> {
    int progress;
    @Override
    protected void onPostExecute(Void result) {
        // TODO Auto-generated method stub
        final Spinner Fahrerauswahl = (Spinner)findViewById(R.id.spinner1);
        final Spinner Fahrzeugauswahl = (Spinner)findViewById(R.id.spinner2);
        final Spinner Nutzungsartauswahl = (Spinner)findViewById(R.id.spinner3);
        Cursor mcursor = (Cursor) Fahrerauswahl.getSelectedItem();
        Fahrer = mcursor.getString(mcursor.getColumnIndexOrThrow("name"));
        FahrerID = mcursor.getString(mcursor.getColumnIndexOrThrow("_id"));
        mcursor.close();
        Cursor mcursor1 = (Cursor) Fahrzeugauswahl.getSelectedItem();
        Kennzeichen = mcursor1.getString(mcursor1.getColumnIndexOrThrow("fahrzeug_kennzeichen"));
        KennzeichenID = mcursor1.getString(mcursor1.getColumnIndexOrThrow("_id"));
        mcursor1.close();
        Cursor mcursor2 = (Cursor) Nutzungsartauswahl.getSelectedItem();
        Nutzungsart = mcursor2.getString(mcursor2.getColumnIndexOrThrow("nutzungsart"));
        NutzungsartID = mcursor2.getString(mcursor2.getColumnIndexOrThrow("_id"));
        mcursor2.close();
        VariablenUebergebenGpsFahrt();
        progressDialog.dismiss();
    }
    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        progressDialog = ProgressDialog.show(Main.this, "GPS", "Ziel-Standort wird ermittelt...");
    }
    @Override
    protected void onProgressUpdate(Integer... values) {
        // TODO Auto-generated method stub
    } 
    @Override
    protected Void doInBackground(Void... arg0) {
        // TODO Auto-generated method stub
        stopService(new Intent(Main.this, GPSService.class));
        return null;
    }    

}

【问题讨论】:

  • 既然您没有在后台做任何事情,那么拥有AsyncTask 有什么意义?这就像用一个空的run() 方法分叉一个线程。
  • 我有一个问题,有时似乎需要很长时间才能调用下一个活动。我正在做的是停止服务(在服务 onDestroy() 中是一些写入 sharedprefs 的值,因此我可以在服务在另一个活动中停止后从服务中读取收集的值),然后从微调器,通过 intent.putextra 移交微调器值,最后通过 startActivity(intent) 调用新活动。对我来说,stopService 似乎花了很多时间,所以我试图在 AsyncTask 中停止它。我错了吗?
  • stopService() 应该不到一毫秒。它不直接做任何事情——服务的实际停止是异步发生的。
  • 但我认为不是我在服务的 onDestroy() 方法中所做的事情。这可能需要更长的时间。
  • 那么你的问题在于服务内部,而不是stopService()调用。

标签: android service android-asynctask progressdialog


【解决方案1】:

这就是我尝试使用 AsyncTask 停止服务的原因。

这无济于事,因为我已尝试在 cmets 中对您的问题进行解释。如果onDestroy() 花费的时间太长,您需要尽快在后台线程中完成这项工作。将stopService() 调用放在后台线程中完全没有意义。

服务本身已经在后台运行,而不是在 UI 线程中。

不,不是。

onDestroy() 在主应用程序线程上调用。 总是

您的服务可能有自己的后台线程用于其他工作,但始终调用生命周期方法(onCreate()onStartCommand()onBind()onDestroy())在主应用程序线程上。

那么如果停止服务需要很长时间,为什么应用会挂起?

因为你在onDestroy()做的工作太多了。

等待停止服务返回的服务和命令不在 UI 线程中运行。

onDestroy() 在主应用程序线程(也称为“UI 线程”)上调用。


更新基于第一条评论:

当我在服务中调用 onDestroy() 时

从不打电话给onDestroy()。 Android 调用onDestroy()。你不是安卓系统。

onDestroy() 不是在服务内部为服务本身调用,而是在主线程中调用?

您似乎认为服务是一个线程。它不是。您可以通过阅读the documentation 来了解这一点(“请注意,服务与其他应用程序对象一样,在其托管进程的主线程中运行。”)。请阅读文档。

【讨论】:

  • 好的,只是为了确保我理解正确。当我在服务内部(而不是在主线程中)调用 onDestroy() 时,不会在服务内部调用 onDestroy() 来为服务本身调用,而是在主线程中调用?在我看来,服务本身有一个 onDestroy() 。不管活动。如果是这样,我怎样才能在服务的 onDestroy() 被调用之前让服务中的停止命令来完成我的工作?目前,在服务中调用 onDestroy() 是了解我的服务已被用户停止的唯一方法。我需要在 stopp 服务上写一些共享首选项。
【解决方案2】:

很难理解为什么会出现 ANR,但似乎您在 onPostExecute() 中执行的很多东西都可以在 doInBackground() 上移动。 Android 开发者建议以异步方式执行 sql lite 操作(Content Provider)和每一个重量级操作。

【讨论】:

    【解决方案3】:

    onPostExecute 中的所有代码都会在 UI 线程上执行,只有 doInBackground 中的代码会在后台执行...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-01
      • 2017-09-08
      • 2013-11-25
      • 2017-08-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多