debugする時に追加している記述の備忘録(2)
はじめに
前回までの話
テスト用に通信鯖をandroid内部に立てたい
キッカケ的な話
の話と絡むのですが、
- AS 2.3-Beta3 InstantRun
- OFFれば確かに問題ないが、使わない前提だとAS Beta2 以降激遅
- Charles Proxyのライセンス絡みのスクリーンロック*1
と重なると開発端末が固まるのですorz *2
なにげに結構ストレスが溜まるのでで、なんとかならないかと思って調べた
ほしいもの
- テスト用のAndroid組み込みサーバーがほしい
- assetとかに置いたjsonファイルでレスポンス返したい
- Charles Proxy の Map Local ライク!
- できれば、httpsのテストがしたい
- MockWebServer::useHttps で可能?
MockWebServerを使うのが現実でないかと
できなかったこと/まだ調べきれてないこと
- MockWebServer::useHttps で証明書をセット
- どうしても証明書関係のエラーが出て、通信ができない*3
- 現状は諦めて httpに変更して使う
- 画像等のバイナリを返すレスポンス
実装的な話
- app/build.gradle
dependencies { compile 'com.squareup.okhttp3:okhttp:3.6.0' debugCompile 'com.squareup.okhttp3:mockwebserver:3.6.0' }
okhttp と mockwebserver のバージョンは揃えること!!
- app/debug/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="hoge.fuga.myapp"> <application android:name=".application.DebugHogeApplication" tools:replace="android:name" /> </manifest>
public class RestUtil{ //URLのSCHEMEの定数 public static String SCHEME_HTTPS = "https"; public static String SCHEME_HTTP = "http"; public static int BASE_PORT_HTTPS = 443; public static int BASE_PORT_HTTP = 80; public static String BASE_SCHEME = SCHEME_HTTP; public static String BASE_HOST = "www.test.jp"; public static int BASE_PORT = BASE_PORT_HTTP; public final static String BASE_MAIN_URL; static{ BASE_MAIN_URL = createBaseUrl(); } //カスタムURL用 public static HttpUrl.Builder createBaseUrl(){ HttpUrl.Builder builder = new HttpUrl.Builder() .scheme(BASE_SCHEME) .host(BASE_HOST) .port(BASE_PORT) .addPathSegment("api") .addPathSegment("v1"); //.addQueryParameter("sensor","false"); return builder; } public static void getApiA(Context context,String address, AsyncOkHttpClient.Callback callback){ HttpUrl.Builder builder = createBaseUrl(); builder.addQueryParameter("address","address"); new RestService(context).get(builder.build(), null, callback); }
public class DebugHogeApplication extends HogeApplication { private MockWebServer server; @Override public void onCreate() { super.onCreate(); //StricModeでNW通信を許可する◎ StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectNetwork() .build()); initServer(); //StricModeを元に戻す◎ StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectAll() .build()); } @Override public void finalize(){ super.onCreate(); shutdown(); } @Override public void onTerminate(){ super.onTerminate(); shutdown(); } private void shutdown(){ if(server != null){ try{ server.shutdown(); }catch (Exception e){ } } } private void initServer(){ server = new MockWebServer(); Dispatcher dispatcher = new Dispatcher() { @Override public MockResponse dispatch(final RecordedRequest request) throws InterruptedException { if (request == null || request.getPath() == null) { return new MockResponse().setResponseCode(400); } MockResponse res = new MockResponse() .addHeader("Content-Type", "application/json") .addHeader("charset", "utf-8") .setResponseCode(200); String path = request.getPath(); switch (path) { case RestUtil.BASE_MAIN_URL + "/hoge": return res.setBody(readJson("hoge.json")); case RestUtil.BASE_MAIN_URL + "/fuga": return res.setBody(readJson("fuga.json")); default: return new MockResponse().setResponseCode(404); } } }; server.setDispatcher(dispatcher); try{ server.start(); RestUtil.BASE_SCHEME = RestUtil.SCHEME_HTTP; RestUtil.BASE_HOST = server.getHostName(); RestUtil.BASE_PORT = server.getPort(); }catch(Exception ex){ shutdown(); server = null; } } private String readJson(String filenme){ InputStream is = null; BufferedReader br = null; String json = ""; try { AssetManager as = getApplicationContext().getResources().getAssets(); is = as.open(filename); br = new BufferedReader(new InputStreamReader(is)); // 1行ずつ読み込み、改行を付加する String str; while ((str = br.readLine()) != null) { json += str + "\n"; } }catch(Exception e){ return ""; } finally { if (is != null){ try { is.close(); } catch (IOException e) { } } if (br != null){ try { br.close(); } catch (IOException e) { } } } return json; } }
- ◎に関して
- 4系の初期頃は、Applicationクラスでの StrictModeの変更が正常に動かない事があったらしい。*4
- 其の場合は、下記の関数で囲むと良いとのこと
//Message Queueの先頭にRunnableを渡す new Handler().postAtFrontOfQueue( new Runnable() { @Override public void run() { //StrickModeの記述 } } );