Android 및 Get 액세스 WebAPI로 Json 처리(일단 Java)

17663 단어 AndroidOkHttpJava
Android의 Http 통신, JSON 처리에도 다양한 옵션이 있기 때문에 가끔 사용하는 사람들은 고통스러워요...
요즘은 OkHttp가 유행인 것 같아서 한번 써보세요.

전제 조건

  • Http 통신은 OkHttp를 사용합니다
  • Json의 퍼스는 JSON Object로 처리합니다(간단한 처리만 하고 추가 라이브러리가 필요하지 않기 때문)
  • 언어는 Java를 사용합니다
  • 개발 환경은 Android Studio3.4입니다.x on Mac
  • 규격


    먼저 버튼을 누르고 WebAPI를 차서 Json, 원근, 디스플레이를 가져옵니다.
    서버에 다음 Json을 반환하는 프로그램이 설정되어 있습니다.
    {"status":"OK","message":"Hello2019-05-31 07:06:23"}
    
  • Json 요청 버튼을 클릭합니다
  • 획득한 Json에서 statu를 꺼내 상기 화면에 표시합니다
  • 다음과 같은 인상.

    준비


    설치 전에 몇 개 준비했어요.

    인터넷 액세스 허용


    AndroidManifest.xml에 다음 내용을 추가합니다.당연하지만 너무 당연하다고 잊어버리는 경우도 있다.
    <uses-permission android:name="android.permission.INTERNET" />
    

    통신 영역 허용 (https 제외)


    Android9인가 봐요.x에서 https 이외의 통신은 오류입니다.다음과 같은 오류가 발생했습니다.
    java.io.IOException: Cleartext HTTP traffic to hoge.com not permitted
    
    hoge.com 은 액세스하려는 도메인, 하위 도메인입니다.
    허용하기 위해서 파일을 설정해야 합니다.귀찮지만 제가 처리할게요.

    설정 파일


    다음 내용을 기록한 xml 파일을 쉽게 만들 수 있습니다.
    또한 파일 이름과 위치는 어디든지 가능한 것 같습니다. (다음 과정에서 명확하게 지정되기 때문입니다.)
    app/res/xml/network_security_config.xml
    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
        <domain-config cleartextTrafficPermitted="true">
            <domain includeSubdomains="true">www.bluecode.jp</domain>
        </domain-config>
    </network-security-config>
    

    프로필 지정


    지정한 설정 파일을 AndroidManifest로 설정합니다.xml에서 지정합니다.
    AndroidManifest.xml
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="jp.bluecode.http01">
    
        <application
    +       android:networkSecurityConfig="@xml/network_security_config"
            android:allowBackup="true"
            ...
    

    OkHttp 설정


    Grandle Module:app에 추가 및 동기화
    ...
    dependencies {
        ...
        implementation 'com.squareup.okhttp3:okhttp:4.0.0-alpha02'
    }
    ...
    
    여기서 끝낼 준비를 하세요.

    실시


    드디어 설치했습니다.오래전부터 주 라인에서 통신 처리를 할 수 없었다.
    다른 라인에서 시작하고 비동기적으로 처리하는 것은 상식이다.OkHttp는 다음과 같습니다.

    MainActivity.java


    MainActivity.java
    package jp.bluecode.http01;
    
    import android.os.Handler;
    import android.os.Looper;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    import org.jetbrains.annotations.NotNull;
    import org.json.JSONObject;
    
    import java.io.IOException;
    
    import okhttp3.Call;
    import okhttp3.Callback;
    import okhttp3.OkHttpClient;
    import okhttp3.Request;
    import okhttp3.Response;
    
    public class MainActivity extends AppCompatActivity {
    
        //Widget宣言
        TextView txt01;
        Button btn01;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //Widget初期化
            txt01 = findViewById(R.id.txt01);
            btn01 = findViewById(R.id.btn01);
    
            //ボタンクリック
            btn01.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    
                    //httpリクエスト
                    try{
                        //okhttpを利用するカスタム関数(下記)
                        httpRequest("http://www.bluecode.jp/test/api.php");
                    }catch(Exception e){
                        Log.e("Hoge",e.getMessage());
                    }
    
                }
            });
        }
    
        void httpRequest(String url) throws IOException{
    
            //OkHttpClinet生成
            OkHttpClient client = new OkHttpClient();
    
            //request生成
            Request request = new Request.Builder()
                    .url(url)
                    .build();
    
            //非同期リクエスト
            client.newCall(request)
                    .enqueue(new Callback() {
    
                        //エラーのとき
                        @Override
                        public void onFailure(@NotNull Call call, @NotNull IOException e) {
                            Log.e("Hoge",e.getMessage());
                        }
    
                        //正常のとき
                        @Override
                        public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
    
                            //response取り出し
                            final String jsonStr = response.body().string();
                            Log.d("Hoge","jsonStr=" + jsonStr);
    
                            //JSON処理
                            try{
                                //jsonパース
                                JSONObject json = new JSONObject(jsonStr);
                                final String status = json.getString("status");
    
                                //親スレッドUI更新
                                Handler mainHandler = new Handler(Looper.getMainLooper());
                                mainHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        txt01.setText(status);
                                    }
                                });
    
    
                            }catch(Exception e){
                                Log.e("Hoge",e.getMessage());
                            }
    
                        }
                    });
        }
    }
    

    activity_main.xml


    레이아웃은 취향에 따라 어떻게 설치해도 좋으니 어쨌든 참고만 가능합니다.
    activity_main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <TextView
            android:id="@+id/txt01"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="200dp"
            android:text="Hello World!"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <Button
            android:id="@+id/btn01"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="32dp"
            android:text="Button"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/txt01" />
    
    </android.support.constraint.ConstraintLayout>
    

    참고 자료


  • https://codeday.me/jp/qa/20190321/444585.html (okhttp)

  • https://tkm0on.hatenablog.com/entry/2015/05/21/183608 (json 퍼스)
  • 좋은 웹페이지 즐겨찾기