【问题标题】:Is it possible to use AsyncTask in a Service class?是否可以在 Service 类中使用 AsyncTask?
【发布时间】:2010-05-01 16:19:47
【问题描述】:

一切都在标题中。

在官方文档中声明Note that services, like other application objects, run in the main thread of their hosting process 和 AsyncTask 只有在 UIThread 中执行时才有效。

那么可以在 Service 类中使用 AsyncTask 吗?

我正在尝试这样做,但我总是遇到同样的错误

05-01 18:09:25.487: ERROR/JavaBinder(270): java.lang.ExceptionInInitializerError

...

05-01 18:09:25.487: ERROR/JavaBinder(270): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

是我做错了什么还是这不可能?

这是我的服务类的代码

package com.eip.core;

import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

public class NetworkService extends Service {


    private final INetwork.Stub mBinder = new INetwork.Stub() {

        @Override
        public int doConnect(String addr, int port) throws RemoteException {
            new ConnectTask().execute("test42");
            return 0;
        }
    };

    @Override
    public IBinder onBind(Intent arg0) {
        return mBinder;
    }

    private class ConnectTask extends AsyncTask<String, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Log.i("OnPreExecute()", "");
        }

        @Override
        protected Void doInBackground(String... arg0) {
            Log.i("doInBackground()", "");
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            Log.i("OnPostExecute()", "");
        }

    }
}

【问题讨论】:

    标签: android multithreading android-asynctask ui-thread


    【解决方案1】:

    还请务必检查 IntentService。如果该类足以满足您的需求,它将处理使该模式正常工作所涉及的许多小细节。

    【讨论】:

      【解决方案2】:

      我想我找到了为什么它在我的情况下不起作用。

      我在这里使用这个:

      private final INetwork.Stub mBinder = new INetwork.Stub() {
      
              @Override
              public int doConnect(String addr, int port) throws RemoteException {
                  new ConnectTask().execute("test42");
                  return 0;
              }
          };
      

      我正在使用它来做所谓的IPC,进程间通信,所以我猜我的Service和我的Activity处于两个不同的进程中,AsyncTask必须在主UI线程中执行到 android 文档,所以根据这些事实,我为什么要这样做似乎是不可能的。

      如果我错了,请有人纠正我。

      【讨论】:

        【解决方案3】:

        也许问题不是 AsyncTask 而是其他问题。例如,您确定您的 onBind 方法可以正常工作吗?请试试这个:

        @Override
        public IBinder onBind(Intent arg0) {
            return null;
        }
        

        你也可以试试

        public class NetworkService extends Service{
          @Override
          public void onStart(Intent intent, int startId) {
            new ConnectTask().execute("test42");
          }
        }
        

        【讨论】:

          【解决方案4】:

          是否可以在 Service 类中使用 AsyncTask?

          是的。请参阅 Reto Meier (2010) Professional Android 2 Application Development,Wrox。 Meier 有published supporting code(参见/Chapter 9 Earthquake 4/src/com/paad/earthquake/EarthquakeService.java):

          public class EarthquakeService extends Service {        
              ... 
              private EarthquakeLookupTask lastLookup = null;
              ...
          
              private class EarthquakeLookupTask extends AsyncTask<Void, Quake, Void> { 
                  ... 
              }
          
              @Override
              public int onStartCommand(Intent intent, int flags, int startId) {    
                  ...
                  refreshEarthquakes();
                  return Service.START_NOT_STICKY;
              };
          
              private void refreshEarthquakes() {
                  ...
                  lastLookup = new EarthquakeLookupTask();
                  lastLookup.execute((Void[])null);
                  ...
              }
          }
          

          顺便说一句,我找不到任何证据来支持您的说法,即“AsyncTask 仅在 UIThread 中执行时才有效”(尽管这将 violate threading rules)。

          【讨论】:

          • 您好,它不违反线程规则,因为您的服务始终在 UI 线程上运行,直到您不从中派生线程
          • 所以上面的代码可以正常工作我猜你对服务和意图服务感到困惑,意图服务默认在后台线程中运行
          【解决方案5】:

          虽然可以use AsyncTask in a Service class,但这违反了线程规则,特别是AsyncTask必须在UI线程上实例化和调用。 (更多讨论请参见https://stackoverflow.com/a/25172977/3664487。)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-12-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多