web-dev-qa-db-ja.com

ServiceクラスでAsyncTaskを使用することは可能ですか?

すべてがタイトルにあります。

公式文書には、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()", "");
        }

    }
}
19
Spredzy

私の場合、なぜそれが機能しないのかを見つけたと思います。

ここで私はこれを使用しています:

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を実行していますプロセス間通信、したがって、サービスとアクティビティは2つの異なるプロセスにあると思います。AsyncTaskは、=に従ってメインUIスレッドで実行する必要があります。 Android doc、だから私がやろうとした理由は、それらの事実によると私には不可能に思えます。

私が間違っている場合は、誰かが私を訂正することができます。

2
Spredzy

また、IntentServiceも必ずチェックしてください。そのクラスがあなたのニーズに十分である場合、それはそのパターンを正しく機能させることに関係する多くの小さな詳細を処理します。

12
hackbod

ServiceクラスでAsyncTaskを使用することは可能ですか?

はい。 Reto Meier(2010)Professional Android 2 Application Development、Wrox。Meierhas published support code (/第9章地震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で実行された場合にのみ機能する」というあなたの主張を裏付ける証拠は見つかりません(ただし、これは- スレッドルールに違反 )。

1
user2768

たぶん問題は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");
  }
}
1
Fedor

AsyncTaskクラスでServiceを使用 することは可能ですが、これはスレッドルールに違反します。 )特に、AsyncTaskは、UIスレッドでインスタンス化して呼び出す必要があります。 (詳細については、 https://stackoverflow.com/a/25172977/3664487 を参照してください。)

0
user2768