5

IntentServiceクラスを作成して実行しましたが、このコード行で が呼び出されるとasyncTask例外が発生しますonPreExecute()pDialog.show();

AsyncHandlerService クラス ---

public class AsyncHandlerService extends IntentService{
ProgressDialog pDialog;
HttpPost post;
HttpResponse response;
Context ctx;

public AsyncHandlerService() {
    super("AsyncHandlerService");
    ctx = this;
}

@Override
protected void onHandleIntent(Intent intent) {
    new LoadDeviceInfo().execute();   
}


class LoadDeviceInfo extends AsyncTask<String, String, String> {

@Override
protected void onPreExecute() {
    super.onPreExecute();
    pDialog = new ProgressDialog(ctx);
    pDialog.setMessage("Updating device info...");
    pDialog.setIndeterminate(false);
    pDialog.setCancelable(false);
    pDialog.show(); //Exception here..
}

protected String doInBackground(String... args) {
}

protected void onPostExecute(String file_url) {
    pDialog.dismiss();
}

アップデート:

Androidマニフェストで定義されIntentServiceたインテントフィルターを持つブロードキャストレシーバーで呼び出しています。android.intent.action.PACKAGE_REPLACEDコード - -

public class OnUpgradeBroadcastReceiver extends BroadcastReceiver {
Context activity;
@Override
    public void onReceive(final Context context, final Intent intent) {
         activity = context;
         Intent msgIntent = new Intent(activity, AsyncHandlerService.class);
            activity.startService(msgIntent);
    }
}

エラーログ:

com.testapp.main fatal error : Unable to add window -- 
token null is not for an application
android.view.WindowManager$BadTokenException: Unable to add window -- 
token null is not for an application
at android.view.ViewRootImpl.setView(ViewRootImpl.java:588)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:326)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
at android.view.WindowManagerImpl$CompatModeWrapper.
addView(WindowManagerImpl.java:149)
at android.app.Dialog.show(Dialog.java:277)
at com.testapp.main.AsyncHandlerService$LoadDeviceInfo.
onPreExecute(AsyncHandlerService.java:62)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
at android.os.AsyncTask.execute(AsyncTask.java:534)
4

5 に答える 5

13

まず、IntentService既にバックグラウンド スレッドを使用しています。別のバックグラウンド スレッドは必要ありません。バックグラウンドで実行する必要がある作業を で実行しますonHandleIntent()

次に、aは aServiceを表示できませんDialog。代わりに、アプリの UI レイヤーに、作業がイベント バス (例: LocalBroadcastManagergreenrobot の EventBus、Square の Otto) 上のメッセージを介して行われたことを知らせます。UI レイヤーがイベントを処理しない場合、必要に応じて、サービスは をNotification発生させるか、実行された作業についてユーザーに知らせることができます。

于 2014-05-29T14:28:20.913 に答える
0

サービスは UI スレッドではありません。
サービス コンテキストからを表示しようとしているためProgressDialog、完了できません。
この解決策を試してください:
https://stackoverflow.com/a/4369755/1405268

于 2014-05-29T14:18:15.117 に答える
0

Intent サービスから Asynctask を呼び出すことはお勧めできません。IntentService から他のスレッドをスピンする必要がある場合は、Executor の使用を検討してください。

ExecutorService es = Executors.newFixedThreadPool(5);
es.execute(new Runnable() {
                @Override
                public void run() {

                }
            });

es.execute(new Runnable() {
                @Override
                public void run() {
                }
            });
es.shutdown();
es.awaitTermination(1, TimeUnit.HOURS);
于 2016-01-15T03:00:32.560 に答える
0

なんらかの理由で本当にAsyncTask 使用したい場合 (たとえば、AsyncTask を使用して Web API を呼び出すようにフレームワークを設定した場合) は、次のように常に待機/通知を使用できます。

public class GetCacheIntentService extends DebuggableIntentService implements ApiAsyncTask.Callback {
    private static final String ACTION_GET_CACHE = "action.GET_CACHE";

    private static final String EXTRA_INT_START = "extras.START";
    private static final String EXTRA_INT_LIMIT = "extras.LIMIT";

    private static final int API_GET_CACHE = 0;

    private final Object mApiCallLock = new Object();
    private GetCacheResponse getCacheResponse;

    public GetCacheIntentService() {
        super("GetCacheIntentService");
        setIntentRedelivery(true);
    }

    public static void startServiceActionGetCache(Context context, int start, int limit) {
        Intent intent = new Intent(context, GetCacheIntentService.class);
        intent.setAction(ACTION_GET_CACHE);
        intent.putExtra(EXTRA_INT_START, start);
        intent.putExtra(EXTRA_INT_LIMIT, limit);
        context.startService(intent);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (intent == null) {
            return;
        }

        String action = intent.getAction();

        if (ACTION_GET_CACHE.equals(action)) {
            int start = intent.getIntExtra(EXTRA_INT_START, 0);
            int limit = intent.getIntExtra(EXTRA_INT_LIMIT, 100);
            getCache(start, limit);
        }
    }

    private void getCache(int start, int limit) {
        GetCacheTask task = new GetCacheTask(this, API_GET_CACHE);
        task.setStart(start);
        task.setLimit(limit);
        task.execute();

        synchronized (mApiCallLock) {
            try {
                mApiCallLock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
                Thread.currentThread().interrupt();
            }
        }

        processResponse(mGetCacheResponse);
    }

    public void processResponse(GetCacheResponse response) {
           // do something
    }

    @Override
    public void onRequestFailed(int id, ApiResponse apiResponse) {
        synchronized (mApiCallLock) {
            switch (id) {
                case API_GET_CACHE:
                    break;
            }
            mApiCallLock.notify();
        }
    }

    @Override
    public void onRequestSuccess(int id, ApiResponse response) {
        synchronized (mApiCallLock) {
            switch (id) {
                case API_GET_CACHE:
                    mGetCacheResponse = (GetCacheResponse) response;
                    break;
            }
            mApiCallLock.notify();
        }
    }
}

これはかなり醜いですが:(

于 2015-04-22T14:09:28.243 に答える