在 AsyncTask.onPostExecute 中調用 TwitterUtils.isAuthenticated(),該方法內部執行網絡請求 twitter.getAccountSettings(),拋出 NetworkOnMainThreadException。原因是 onPostExecute 運行在主線程,Android 4.0+ 禁止主線程執行網絡操作。
class CallNetworkMethod extends AsyncTask {
// 使用 Boolean 作為結果類型,直接返回認證狀態
@Override
protected Boolean doInBackground(Void... params) {
// 關鍵:在後台線程執行網絡請求
return TwitterUtils.isAuthenticated(prefs);
}
@Override
protected void onPostExecute(Boolean isAuthenticated) {
// 主線程更新 UI
loginStatus.setText("Logged into Twitter: " + isAuthenticated);
// 可根據結果進一步處理
if (isAuthenticated) {
// 已認證邏輯
} else {
// 未認證,跳轉授權頁面
Intent i = new Intent(getApplicationContext(), TwPrepareRequestTokenActivity.class);
i.putExtra("tweet_msg", getTweetMsg());
startActivity(i);
}
}
}
public class TwitterUtils {
public static boolean isAuthenticated(SharedPreferences prefs) {
String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");
AccessToken a = new AccessToken(token, secret);
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(TwConstants.CONSUMER_KEY, TwConstants.CONSUMER_SECRET);
twitter.setOAuthAccessToken(a);
try {
twitter.getAccountSettings(); // 網絡請求
return true;
} catch (TwitterException e) {
return false;
}
}
}
| 參數 | 含義 | 本例 |
|---|---|---|
| Params | 執行參數類型 | Void(無參數) |
| Progress | 進度類型 | Void(無進度) |
| Result | 結果類型 | Boolean(認證結果) |
AsyncTask 已在 Android 11 (API 30) 棄用,建議使用:
// ViewModel 中
viewModelScope.launch {
try {
val isAuth = withContext(Dispatchers.IO) {
TwitterUtils.isAuthenticated(prefs)
}
_loginStatus.postValue("Logged into Twitter: $isAuth")
} catch (e: Exception) {
_loginStatus.postValue("Error: ${e.message}")
}
}
Observable.fromCallable(() -> TwitterUtils.isAuthenticated(prefs))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(isAuth -> loginStatus.setText("Logged: " + isAuth),
error -> loginStatus.setText("Error: " + error.getMessage()));
ExecutorService executor = Executors.newSingleThreadExecutor();
Handler mainHandler = new Handler(Looper.getMainLooper());
executor.execute(() -> {
boolean isAuth = TwitterUtils.isAuthenticated(prefs);
mainHandler.post(() -> loginStatus.setText("Logged: " + isAuth));
});
StrictMode.ThreadPolicy 開發期檢測主線程違規。lifecycleScope/viewModelScope 自動取消。