Android StudioはEclipseに取って代わりそうな?Androidアプリの開発環境(IDE)です。
(公式サイト)
https://developer.android.com/sdk/installing/index.html?pkg=studio
Android StudioはEclipseに取って代わりそうな?Androidアプリの開発環境(IDE)です。
(公式サイト)
https://developer.android.com/sdk/installing/index.html?pkg=studio
StrictModeとは、メインスレッド内で予期せぬディスクアクセスや、ネットワークアクセスなどにより時間がかかる処理などをしている場合、それを教えてくれます。より、サクサク動くアプリを作るための、開発者向けのクラスです。
つまり、これを使って時間がかかっている処理を暴けば、ANRが少なくできるであろう!というわけです。
http://developer.android.com/reference/android/os/StrictMode.html
これを実装してみます。
単一の画面で調べたい場合は、その画面のActivityのOnCreateに書けばよいのですが、あらゆる画面で調べたい!と欲張りな私は、以前にGoogle Playで配布しないアプリにクラッシュログ機能を実装するで書きました、MyApplication.javaの中で実装します。
public class MyApplication extends Application { @Override public void onCreate() { // The following line triggers the initialization of ACRA super.onCreate(); ACRA.init(this); Log.d("Application", "MyApplication"); if (AppConstants.IS_STRICT_ON) { StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() .detectDiskReads() .detectDiskWrites() .detectNetwork() // or .detectAll() for all detectable problems .penaltyLog() .build()); StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() .detectLeakedClosableObjects() .penaltyLog() .penaltyDeath() .build()); } } }
アプリを実行します。
すると、とある処理で、アプリが落ち、LogCatにエラーが表示されます。
06-25 13:10:43.585: E/StrictMode(21309): Finalizing a Cursor that has not been deactivated or closed. database = /data/data/hogehoge.appli/databases/hoge, table = null, query = select * from LocationTable 06-25 13:10:43.585: E/StrictMode(21309): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here 06-25 13:10:43.585: E/StrictMode(21309): at android.database.sqlite.SQLiteCursor.<init>(SQLiteCursor.java:98) 06-25 13:10:43.585: E/StrictMode(21309): at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:50) 06-25 13:10:43.585: E/StrictMode(21309): at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1322) 06-25 13:10:43.585: E/StrictMode(21309): at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1261) 06-25 13:10:43.585: E/StrictMode(21309): at hogehoge.appli.helper.SqliteDataBaseHelper.getAllData(SqliteDataBaseHelper.java:163)
なぬっ
SQLiteのSELECTで使うカーソルが、閉じ忘れだそうです。
Cursor c = db.rawQuery("select * from " + SqliteDataBaseHelper.DB_TABLE, null); //この後 c.close(); を実装しなければならなかったのに忘れていた
ふぅ~
見つかってよかった
と、このように便利なツールですね!!
ちなみに、
http://developer.android.com/reference/android/os/StrictMode.html
を読んで勉強になったのが、Androidのファイルシステムは通常フラッシュメモリなので、I/Oが早いはずなのですが、他のプロセスと並行するためのメモリ割り当ては大変少ないので、他のプロセスと同時に書き込まれる場合はとっても遅くなる場合があるらしいです。
スピナーにデフォルトの値を設定する方法です。
prefectureSpinner = (Spinner) findViewById(R.id.prefecture); if(tempo_prefecture != null){ ArrayAdapter myAdap = (ArrayAdapter) prefectureSpinner.getAdapter(); int spinnerPosition = myAdap.getPosition(tempo_prefecture); prefectureSpinner.setSelection(spinnerPosition); }
下記を参考にさせて頂きました。
http://stackoverflow.com/questions/2390102/how-to-set-selected-item-of-spinner-by-value-not-by-position
SpinnerとはHTMLで言うリストみたいなものです。
valueを取得するには、↓
String item = (String) spinner.getSelectedItem();
のようにすればよいのですが、keyを取得するのは難しいです。
苦肉の策で、リストの順番だけは、下記のように取得できるので、これを使うことにしました。
String item = (String) spinner.getSelectedItemId();
何度かこのエラーに引っかかっている私ですが…
java.lang.RuntimeException: Unable to instantiate service hogehoge.project.services.FetchAddressIntentService: java.lang.InstantiationException: can’t instantiate class hogehoge.project.services.FetchAddressIntentService; no empty constructor
下記のようなエラーが出て、IntentServiceが起動できない時があります。
コンストラクタがないよって言われてますが、下記のように、コンストラクタはありまぁす!
public class FetchAddressIntentService extends IntentService { public static final int SUCCESS_RESULT = 0; public static final int FAILURE_RESULT = 1; public static final String PACKAGE_NAME = "smart.location.admin.edison"; public static final String RECEIVER = PACKAGE_NAME + ".RECEIVER"; public static final String RESULT_DATA_KEY = PACKAGE_NAME + ".RESULT_DATA_KEY"; public static final String LOCATION_DATA_EXTRA = PACKAGE_NAME + ".LOCATION_DATA_EXTRA"; public static final String TAG = "FetchAddressIntentService"; protected ResultReceiver mReceiver; public FetchAddressIntentService(String name) { super(name); }
AndroidManifest.xmlにもサービスを記載してあるし、なんでだよ…っ!!
と思いますが、下記の記事によると
http://stackoverflow.com/questions/11859403/no-empty-constructor-when-create-a-service
引数のないコンストラクタを作らないといけない。
そうです。ふぎゃぁ。
というわけで、上記に下記を追加したら、IntentServiceが起動するようになりました!
public FetchAddressIntentService() { super("FetchAddressIntentService"); }