7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Twitter4Jでユーザフォロー時にandroid.os.NetworkOnMainThreadExceptionが発生した場合の対処法

Last updated at Posted at 2014-06-02

Twitter4J を使って、Android アプリ上で Twitter のフォロー機能を実現しようとした時に少しはまったので、その解決方法のメモを置いておきます。

次の followTwitterUser() メソッドを実行すると android.os.NetworkOnMainThreadException エラーが発生し、アプリが強制終了してしまいました。なぜ?

java
public void followTwitterUser(String username) {
    // Twitter インスタンスの取得
    Twitter twitter = TwitterUtils.getTwitterInstance(this);

    // TwitterUtils クラスは以下のページを参照:
    //    Android再入門 - Twitterクライアントを作ってみよう
    //    http://qiita.com/gabu/items/f6f39900fd5e449045f9
    
    try {
        // Twitter フォロー実行
        twitter.createFriendship(username);
    } catch (TwitterException e) {
        e.printStackTrace();
    }
}
java
String username = "twitter";
followTwitterUser(username);

エラーの内容は以下の通り。

android.os.NetworkOnMainThreadException
FATAL EXCEPTION: main
android.os.NetworkOnMainThreadException
    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1133)
    at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:708)
    at java.io.BufferedOutputStream.flushInternal(BufferedOutputStream.java:185)
    at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:85)
    at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:824)
    at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:283)
    at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:497)
    at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:134)
    at twitter4j.HttpResponseImpl.<init>(HttpResponseImpl.java:35)
    at twitter4j.HttpClientImpl.handleRequest(HttpClientImpl.java:143)
    at twitter4j.HttpClientBase.request(HttpClientBase.java:53)
    at twitter4j.HttpClientBase.post(HttpClientBase.java:82)
    at twitter4j.TwitterImpl.post(TwitterImpl.java:1986)
    at twitter4j.TwitterImpl.createFriendship(TwitterImpl.java:480)
(以下省略)

エラー中にある AndroidBlockGuardPolicy.onNetwork というキーワードで調べてわかったのですが、どうやら Android 4.0 以降は、Main スレッド( UI スレッド)上でネットワーク通信を行うとこのエラーが発生するようです。

このエラーを回避するには、ネットワーク通信を別スレッド(サブスレッド)で実行する必要があります。サブスレッドで非同期処理を行う AsyncTask を作って doInBackground()コールバック内でネットワーク通信が必要な処理(Twitterのフォロー)を実行するように書き換えます。

java
// サブスレッドから参照できるように Twitter クラスのインスタンスを保持する変数はメンバ変数にしておく
// 例:
// public class TwitterActivity extends Activity {
//
//     private Twitter mTwitter = null;
//     // ...(以下省略)
// }

public void followTwitterUserAsync(String username) {
    // Twitter インスタンスの取得
    mTwitter = TwitterUtils.getTwitterInstance(this);

    // サブスレッドで実行するタスクを作成
    AsyncTask<String, Void, Boolean> task = new AsyncTask<String, Void, Boolean>() {
        @Override
        protected Boolean doInBackground(String... params) {
            username = params[0];
            try {
                // Twitter フォロー実行
                mTwitter.createFriendship(username);
                return true;
            } catch (TwitterException e) {
                e.printStackTrace();
                return false;
            }
        }
		
        @Override
        protected void onPostExecute(Boolean followResult) {
            if (followResult) {
                // フォロー成功時の処理
            } else {
                // フォロー失敗時の処理
            }
        }
    };
    task.execute(username);
}
java
String username = "twitter";
followTwitterUserAsync(username);

これで Twitter フォローができるようになりました。
ネットワーク通信を伴う処理はサブスレッドで実行する、というのがミソですね。

7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?