IntentService からネットワーク呼び出しを行っていますが、まだ NetworkOnMainThreadException を受け取ります。私の理解では、IntentService は常にワーカー スレッドで実行されるので、これを見て驚いています。重要な部分は、私の IntentService がネットワーク呼び出しを実行する静的ヘルパー クラスを呼び出していることです。静的ヘルパー クラスは、メインの Application クラスでインスタンス化されます。
これは IntentService のワーカー スレッドで引き続き実行されると思いました。私は何が欠けていますか?
正直なところ、私は迅速なコード修正よりも、有益な議論を好む. ただし、コードが必要な場合は、コードを提供する必要があります。
//MyApplication.java
public class MyApplication extends Application{
private static NetworkUtils utils;
@Override
public void onCreate() {
super.onCreate();
utils = new NetworkUtils(this);
...
}
...
}
//NetworkUtils.java
public class NetworkUtils {
private static Context context;
private static final Gson gson = new Gson();
public NetworkUtils(Context context) {
this.context = context;
}
public static final DataResponse login(String email, String password) {
//*** NetworkOnMainThreadException OCCURS HERE ***
DataResponse response = HttpConnection.put(url, json);
...
return response;
}
...
}
//LoginService.java
public class LoginService extends IntentService {
public LoginService() {
super("LoginService");
}
@Override
public void onStart(Intent intent, int startId) {
onHandleIntent(intent);
}
@Override
protected void onHandleIntent(Intent intent) {
Bundle bundle = new Bundle();
DataResponse response = NetworkUtils.login(email, password);
...
bundle.putBoolean(MyConstants.ExtraKeys.LOGGED, response.success);
MainApplication.getApplicationInstance().sendBroadCast(MyConstants.Actions.LOGIN, bundle);
}
}
//LoginActivity.java
public class LoginActivity extends ActionBarActivity implements IDialogClickListener {
...
public void onLoginButtonPressed() {
Intent intent = new Intent(MainApplication.getApplicationInstance(), LoginService.class);
this.startService(intent);
}
}
また、Logcat:
> 04-01 18:20:41.048: VERBOSE/com.foo.foo(28942):
> com.foo.foo.network.HttpConnection.execute - METHOD: PUT
> 04-01 18:20:41.068: ERROR/com.foo.foo(28942):
> com.foo.foo.social.NetworkUtils.login - class
> android.os.NetworkOnMainThreadException: null
> 04-01 18:20:41.169: DEBUG/com.foo.foo(28942):
> com.foo.foo.MainActivity$MyReceiver.onReceive - BROADCAST RECEIVED:
> com.foo.foo.MainApplication@422d81d8 - Intent { act=com.foo.foo.login
> dat=com.foo.foo.scheme://data/1364854841079 (has extras) }
> 04-01 18:20:41.169: INFO/com.foo.foo(28942):
> com.foo.foo.activity.LoginActivity.setData - ACTION: com.foo.foo.login
> - ISERROR: true
解決
onHandleIntent
根本的な問題は、明示的に呼び出していた少しのレガシー コードでした。上記の LoginService.java では:
@Override
public void onStart(Intent intent, int startId) {
onHandleIntent(intent);
}
これにより、onHandleIntent コードが onStart イベント (明らかにメイン スレッドで実行される) から呼び出されるため、メイン スレッドで実行されます。