LoginSignup
0
0

More than 3 years have passed since last update.

[ Android Studio ] [ HTTP ] 非同期処理 サーバクライアント通信3

Posted at

引き続きHTTP通信でデータを取得する方法を述べていく。

前回は「NetworkOnMainThreadException」がでたところで記事を終えたので、
その解決法について述べる。

NetworkOnMainThreadException

Android3.0から
メインスレッド(UIスレッド)からの通信が禁止されたため起こるエラー。

簡単に言うと、
HTTP通信を非同期処理で行わなければならない。

非同期処理実装の流れ

まず、
非同期処理用クラス( AsyncTaskを継承 )を新たに作成する。
オーバーライドしたdoInBackground()へURLを渡し、HTTP通信を行う。
doInBackground()の返り値はonPostExecute()の引数に渡され、
そこでHTTP接続後の処理を行う。
*具体的な処理は一番下ののサンプルを見て頂きたい。

MyAsync.java

public class MyAsync extends AsyncTask<String, Void, String> {
    private Activity mActivity;
    MainActivity mainActivity = new MainActivity();

    public MyAsync(Activity activity) {
        mActivity = activity;
    }
    public interface ResponseListener {
        void onResponseDataReceived(String responseData);
    }

  //引数paramsにURLを渡す
    @Override
    protected String doInBackground(String... params) {
     //HTTP通信処理
     //サーバから取得したデータをString型変数に格納
        return String型変数; //onPostExecuteの引数に渡す
    }

    @Override
    public void onPostExecute(String string) {
        //Text表示処理
    }
}

呼び出し側は以下の通りにして、非同期処理を実行する。
onCreate内でMyAsyncを呼び出すだけである。

MainActivity.java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new MyAsync(this).execute("URL"); //非同期処理呼び出し
    }

これでエラーを解消することができた。
参考URL:http://shiro-16.hatenablog.com/entry/2014/03/25/004856

まとめ

かなり時間がかかったが、何とかHTTP通信を成功させることができた。
サーバクライアント通信について3つの記事を書いてきたが、
以下がポイントである。

HTTP通信は非同期処理が必要。(Android 3.0以降)
 忘れるとNetworkOnMainThreadExceptionで怒られる。
HTTP通信を許可するための記述の追加が必要
 忘れるとCleartext HTTP traffic not permittedで怒られる。
 こちらを参考にしてください。
 https://qiita.com/QiitaD/items/ba4124d791c39a82783a

以上のことを気を付けて頂きたい。

サンプル(AsyncTask.java)

このサンプルはTextViewにより、サーバから取得したXMLソースコードを表示するものである。
レイアウトファイルに表示用のTextViewがなければ何も起こらないので注意していただきたい。

public class MyAsync extends AsyncTask<String, Void, String> {
    private Activity mActivity;

    public MyAsync(Activity activity) {
        mActivity = activity;
    }
    public interface ResponseListener {
        void onResponseDataReceived(String responseData);
    }

    @Override
    protected String doInBackground(String... params) {

        HttpURLConnection connection = null;
        StringBuilder src = new StringBuilder();
        try {
            URL url = new URL(params[0]);
            connection = (HttpURLConnection) url.openConnection();    //HTTP通信処理開始

            connection.setRequestMethod("GET");
            connection.addRequestProperty("User-agent", "Android");
            connection.addRequestProperty("Accept-Language", Locale.getDefault().toString());
            connection.setInstanceFollowRedirects(false); 
            connection.setDoInput(true);                  
            connection.setDoOutput(false);
            connection.setConnectTimeout(20000);          
            connection.setReadTimeout(30000);

            //データ取得
            InputStream is = connection.getInputStream();
            while (true) {
                byte[] line = new byte[1024];
                int size = is.read(line);
                if (size <= 0)
                    break;
                src.append(new String(line, "utf-8"));
            }

            if (is != null){
                is.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            connection.disconnect();  //HTTP通信終了
        }
        return new String(src);  //取得データを返す
    }

  //引数に渡されたデータをTextViewで表示
    public void onPostExecute(String string) {
        TextView textView = (TextView) mActivity.findViewById(R.id.response);
        textView.setText(string);
    }
}

0
0
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
0
0