2016-05-17 1 views
1

から拒否されたため、Android GCMがクラッシュすることがありました。アプリがクラッシュすることがあり、ログに次の例外が表示されることがあります。GCMを8.4.0にアップグレードして以来、com.google.android.gms.GcmListenerServiceがjava.util.concurrent.ThreadPoolExecutor

Fatal Exception: java.lang.RuntimeException: Unable to start service [email protected] with Intent { act=com.google.android.c2dm.intent.RECEIVE flg=0x10000010 pkg=com.myapp.app cmp=com.myapp.app/.Service_GCMListenerService (has extras) }: java.util.concurrent.RejectedExecutionException: Task [email protected] rejected from [email protected][Running, pool size = 9, active threads = 9, queued tasks = 128, completed tasks = 0] 
     at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3027) 
     at android.app.ActivityThread.-wrap17(ActivityThread.java) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1442) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
     at android.os.Looper.loop(Looper.java:148) 
     at android.app.ActivityThread.main(ActivityThread.java:5417) 
     at java.lang.reflect.Method.invoke(Method.java) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
Caused by java.util.concurrent.RejectedExecutionException: Task [email protected] rejected from [email protected][Running, pool size = 9, active threads = 9, queued tasks = 128, completed tasks = 0] 
     at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2014) 
     at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:794) 
     at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1340) 
     at com.google.android.gms.gcm.GcmListenerService.zzn(Unknown Source) 
     at com.google.android.gms.gcm.GcmListenerService.onStartCommand(Unknown Source) 
     at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3010) 
     at android.app.ActivityThread.-wrap17(ActivityThread.java) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1442) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
     at android.os.Looper.loop(Looper.java:148) 
     at android.app.ActivityThread.main(ActivityThread.java:5417) 
     at java.lang.reflect.Method.invoke(Method.java) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

このクラッシュでは、私のコードのどこにエラーがあるのか​​説明していません。私は何をすべきか?

これはGCMの私の実装です:

Androidのマニフェスト

<receiver 
     android:name="com.google.android.gms.gcm.GcmReceiver" 
     android:exported="true" 
     android:permission="com.google.android.c2dm.permission.SEND" > 
     <intent-filter> 
      <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
      <category android:name="com.myapp.app" /> 
     </intent-filter> 
    </receiver> 

    <service 
     android:name=".Service_GCMListenerService" 
     android:exported="false" > 
     <intent-filter> 
      <action android:name="com.google.android.c2dm.intent.RECEIVE" /> 
     </intent-filter> 
    </service> 
    <service 
     android:name=".Service_IDListenerService" 
     android:exported="false"> 
     <intent-filter> 
      <action android:name="com.google.android.gms.iid.InstanceID"/> 
     </intent-filter> 
    </service> 

Service_GCMListenerService

public class Service_GCMListenerService extends GcmListenerService { 



    @Override 
    public void onDeletedMessages() { 
     super.onDeletedMessages(); 

     PushManager.checkForNewPush(); 
    } 

    @Override 
    public void onMessageReceived(String from, Bundle data) { 
     super.onMessageReceived(from, data); 

     PushManager.processPush(this,false,data.getString("message")); 
    } 


} 

Service_IDListenerService

public class Service_IDListenerService extends InstanceIDListenerService { 

/** 
* Called if InstanceID token is updated. This may occur if the security of 
* the previous token had been compromised. This call is initiated by the 
* InstanceID provider. 
*/ 
@Override 
public void onTokenRefresh() { 
    GCMUtils.registerNewInstanceID(); 
} 
+0

コードを共有していただけますか? – Teyam

+0

コードが追加されました – Meroelyth

+0

私はまったく同じ問題があります。また、Mixpanelも使用しています。あなたはこれに対する解決策を見つけましたか? – crysxd

答えて

1

AsyncTaskのTHREAD_POOL_EXECUTORには128個のタスクがハードコードされています。問題は、そのエグゼキュータで多くのタスクを実行していることです。

いずれのAsyncTasksに対しても直接executeOnExecutorを呼び出さない場合は、特にネットワーク操作を実行するものがListenableFutureを返すサードパーティのメソッドが原因である可能性が最も高いです。おそらく、それらを連続して実行する方法が必要でしょう。これらの操作のすべてをAsyncTask.SERIAL_EXECUTORで実行されるAsyncTasksに移動することは、1つの解決策になります。

+0

アドバイスありがとうございますが、サービスcom.myapp.app.Service_GCMListenerServiceがAndroidから直接呼び出されるため、AsyncTaskを直接呼び出すことはありません。 – Meroelyth

+0

私は参照してください。私の答えの後半部分は助けとなりましたか? ThreadPoolExecutorのどこかにブレークポイントを設定して、どのメソッドがスレッドを実行しているかを調べることができると思います。 – Haem

+0

@Meroelythコメントの補足として、ブレークポイントを設定するメソッドは 'ThreadPoolExecutor.execute'です。問題を見つけるためにクラッシュを再現する必要はありません。コード内でメソッド呼び出しが 'ThreadPoolExecutor'で実行される' AsyncTask'を生成する場所を特定する必要があります。 – Haem

関連する問題