Android Java 非同期でサーバーからJSONデータを取得する


今回はサーバーからJSONデータを取得して処理する方法のメモです。
AsyncTaskLoaderってのを使用します。

## 検証環境
|環境|
|:--:|
|Android Studio 1.1.0|
|minSdkVersion API 18: Android 4.3 (Jelly Bean)|

## HOW TO

↓こんなかんじのJSONデータを取得すると仮定します。

```txt:JSON
{
    "data": {
        "venue": {
            "id": "2",
            "venue_id": "1001",
            "name": "大阪"
        },
        "exhibitor": [
            {
                "id": "1",
                "manufacturer_no": "S01",
                "name": "SnowRobin１"
            },
            {
                "id": "2",
                "manufacturer_no": "S02",
                "name": "SnowRobin２"
            }
        ]
    }
}
```

Android Javaのコードね↓

```Java:AnyActivity.java
public class AnyActivity extends ActionBarActivity {

	public JsonManager jm;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		// JsonManagerのインスタンス生成
		jm = new JsonManager(this);
		// Jsonデータ取得
		jm.runDataLoader();
	}
}
```

```Java:JsonManager.java
import android.app.LoaderManager;
import android.content.Loader;
import android.os.Bundle;
import android.util.Log;

import org.json.JSONException;
import org.json.JSONObject;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import jp.co.any.Activities.AnyActivity;
import jp.co.any.Loaders.JsonLoader;

public class JsonManager implements LoaderManager.LoaderCallbacks<JSONObject> {

    private AnyActivity activity;
    private String url;
    List<Exhibitor> exhibitorList;

    public JsonManager(AnyActivity activity) {
        this.activity = activity;
    }


	public void runDataLoader() {	
		this.url = "URL";
		this.activity.getLoaderManager().initLoader(0, null, this);
	}

    @Override
    public Loader<JSONObject> onCreateLoader(int id, Bundle args) {
        JsonLoader jsonLoader = new JsonLoader(this.activity.getApplicationContext(), this.url);
        jsonLoader.forceLoad();
        return jsonLoader;
    }

    @Override
    public void onLoadFinished(Loader<JSONObject> loader, JSONObject data) {
        try {
			JSONObject json_obj = data.getJSONObject("data");
			if (json_obj.has("venue")) {
				// 構造体に渡す
				Venue venue = new Venue(json_obj.getJSONObject);
			}
			if (json_obj.has("exhibitor")) {
				this.exhibitorList = new ArrayList<Exhibitor>();
				JSONArray exhibitors = json_obj.getJSONArray("exhibitor")
				for (int idx = 0; idx < exhibitors.length(); idx++) {
					// 構造体に渡す
					Exhibitor exhibitor = new Exhibitor(exhibitors.getJSONObject(idx));
					// 配列に入れる
					exhibitorList.add(exhibitor);
				}
			}
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onLoaderReset(Loader<JSONObject> loader) {

    }
    
```


```Java:JsonLoader.java

import android.content.AsyncTaskLoader;
import android.content.Context;
import android.util.Log;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;


public class JsonLoader extends AsyncTaskLoader<JSONObject>{

    private String urlText;

    public JsonLoader(Context context, String urlText) {
        super(context);
        this.urlText = urlText;
    }

	// 非同期処理
    @Override
    public JSONObject loadInBackground() {
        HttpClient httpClient = new DefaultHttpClient();

        StringBuilder uri = new StringBuilder(urlText);
        HttpGet request = new HttpGet(uri.toString());
        HttpResponse httpResponse = null;
        try {
            httpResponse = httpClient.execute(request);
        } catch (Exception e) {
            Log.d("test", "Error Execute" + e);
            return null;
        }

        int status = httpResponse.getStatusLine().getStatusCode();
        if (HttpStatus.SC_OK == status) {
            try {
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                httpResponse.getEntity().writeTo(outputStream);
                String data;
                data = outputStream.toString(); // JSONデータ

                JSONObject rootObject = new JSONObject(data);
                Log.d(Const.TAG, "" + rootObject);
                return rootObject;

            } catch (Exception e) {
                Log.d(Const.TAG, "Error:" + e);
            }
        } else {
            return null;
        }
        return null;
    }
}

```

一応構造体も書いておきます↓

```Java:Venue.java

public class Venue {
    private String id;
    private String venue_id;
    private String name;

    public Option(JSONObject json) throws JSONException {
        this.id = json.getString("id");
        this.name = json.getString("venue_id");
        this.language = json.getString("name");
    }
}

```

```Java:Exhibitor.java
public class Exhibitor {
    private String id;
    private String manufacturer_no;
    private String name;

    public Option(JSONObject json) throws JSONException {
        this.id = json.getString("id");
        this.name = json.getString("manufacturer_no");
        this.language = json.getString("name");
    }
}
```

こんな感じでしょうか？
一応構造体に渡すまでやってますが、好きにDBに入れるなり好きに加工してもらったらいいと思います。

## 余談
ちなみにiOS SwiftのJSONのデータを取得してくる方法はこちら↓
[Swift 非同期でサーバーからJSONデータを取得する](http://qiita.com/kntr/items/b661d8232c05cfb0dbdc)