代码之家  ›  专栏  ›  技术社区  ›  Spredzy

是否可以在服务类中使用AsyncTask?

  •  18
  • Spredzy  · 技术社区  · 15 年前

    一切都在标题中。

    在官方文件中规定 Note that services, like other application objects, run in the main thread of their hosting process 只有在uithread中执行asyncTask时,它才能工作。

    那么可以在服务类中使用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()", "");
            }
    
        }
    }
    
    5 回复  |  直到 10 年前
        1
  •  12
  •   hackbod    15 年前

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

        2
  •  2
  •   Spredzy    15 年前

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

    这里我使用这个:

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

    我用这个做所谓的工控机, 进程间通信 ,所以我猜我的服务和我的活动处于两个不同的过程中,异步任务必须根据android文档在主UI线程中执行,所以根据这些事实,我为什么要尝试这样做似乎是不可能的。

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

        3
  •  1
  •   Fedor    15 年前

    也许问题不是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
  •  1
  •   Community CDub    8 年前

    是否可以在服务类中使用AsyncTask?

    对。见Reto Meier(2010) 专业安卓2应用开发 ,WROX。迈耶有 published supporting code (参阅/第9章地震4/SRC/COM/PAAD/地震/地震服务)

    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);
            ...
        }
    }
    

    顺便说一句,我找不到任何证据支持你的说法。” 只有在UIThread中执行AsyncTask时,它才起作用 “(尽管这会 violate threading rules )

        5
  •  0
  •   Community CDub    8 年前

    尽管有可能 use AsyncTask in a Service class 这违反了 线程规则 尤其是, 异步任务 必须在UI线程上实例化和调用。(见 https://stackoverflow.com/a/25172977/3664487 供进一步讨论。)