Android
例外
サーチ…
NetworkOnMainThreadException
ドキュメントから:
アプリケーションがメインスレッドでネットワーク操作を実行しようとしたときにスローされる例外です。
これは、Honeycomb SDK以上をターゲットとするアプリケーションでのみスローされます。以前のバージョンのSDKを対象としたアプリケーションでは、メインイベントループスレッドでネットワーキングを行うことが許可されていますが、あまり推奨されません。
その例外を引き起こす可能性があるコードの例を次に示します。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Uri.Builder builder = new Uri.Builder().scheme("http").authority("www.google.com");
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
URL url;
try {
url = new URL(builder.build().toString());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
} catch (IOException e) {
Log.e("TAG","Connection error", e);
} finally{
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("TAG", "Error closing stream", e);
}
}
}
}
}
上記のコードは、アプリケーションがメインスレッド上でネットワーク操作を実行しようとしているため、Honeycomb SDK(Android v3.0)以上をターゲットとするアプリケーションに対してNetworkOnMainThreadException
をスローします。
この例外を回避するには、ネットワーク操作を常にAsyncTask
、 Thread
、 IntentService
などのバックグラウンドタスクで実行する必要があります。
private class MyAsyncTask extends AsyncTask<String, Integer, Void> {
@Override
protected Void doInBackground(String[] params) {
Uri.Builder builder = new Uri.Builder().scheme("http").authority("www.google.com");
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
URL url;
try {
url = new URL(builder.build().toString());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
} catch (IOException e) {
Log.e("TAG","Connection error", e);
} finally{
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("TAG", "Error closing stream", e);
}
}
}
return null;
}
}
ActivityNotFoundException
これは非常に一般Exception
なException
です。これにより、アプリケーションの起動または実行中にアプリケーションが停止します。 LogCat
メッセージが表示されます:
android.content.ActivityNotFoundException : Unable to find explicit activity class;
have you declared this activity in your AndroidManifest.xml?
この場合、 AndroidManifest.xml
ファイルでアクティビティを宣言しているかどうかを確認してください。
AndroidManifest.xml
でActivity
を宣言する最も簡単な方法は次のとおりです。
<activity android:name="com.yourdomain.YourStoppedActivity" />
OutOfMemoryError
これは、ヒープ上に大量のメモリを要求すると発生するランタイムエラーです。これは、ビットマップをImageViewにロードするときによく起こります。
いくつかの選択肢があります:
- 大規模なアプリケーションヒープを使用する
AndroidManifest.xmlのapplicationタグに "largeHeap"オプションを追加します。これにより、アプリで使用できるメモリが増えますが、根本的な問題は解決されない可能性があります。
<application largeHeap="true" ... >
- ビットマップをリサイクルする
ビットマップを読み込んだ後、リサイクルしてメモリを解放してください。
if (bitmap != null && !bitmap.isRecycled())
bitmap.recycle();
- サンプリングされたビットマップをメモリにロードする
BitmapOptionsとinSampleSizeを使用して、ビットマップ全体を一度にメモリにロードしないでください。
たとえば、 Androidのドキュメントを参照してください
DexException
com.android.dex.DexException: Multiple dex files define Lcom/example/lib/Class;
このエラーは、パッケージング時に、同じメソッドセットを定義する2つの.dex
ファイルを検出するために発生します。
通常、これは、アプリケーションが誤って同じライブラリに2つの別個の依存関係を取得したために発生します。
たとえば、プロジェクトがあり、それぞれに独自の依存関係を持つ2つのライブラリA
とB
を使用したいとします。ライブラリーB
すでにライブラリーA
に依存している場合、ライブラリーA
が単独でプロジェクトに追加されると、このエラーがスローされます。ライブラリB
コンパイルするとすでにA
からコードのセットが与えられていたので、コンパイラがライブラリA
をバンドルA
、パッケージA
のメソッドが既にパッケージ化されています。
解決するには、あなたの依存関係のどれもが誤ってこのように2回追加されないようにしてください
捕捉されなかった例外
キャッチされていない例外を処理したい場合は、それらをonCreateメソッドですべてキャッチしようとするアプリケーションクラス:
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
try {
Thread
.setDefaultUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable e) {
Log.e(TAG,
"Uncaught Exception thread: "+thread.getName()+"
"+e.getStackTrace());
handleUncaughtException (thread, e);
}
});
} catch (SecurityException e) {
Log.e(TAG,
"Could not set the Default Uncaught Exception Handler:"
+e.getStackTrace());
}
}
private void handleUncaughtException (Thread thread, Throwable e){
Log.e(TAG, "uncaughtException:");
e.printStackTrace();
}
}
予期しない例外に対するハンドラーの登録
これは、システムの標準「アプリケーションXYZがクラッシュしました」と同様に、キャッチされていない例外にどのように対応できるかです。
import android.app.Application;
import android.util.Log;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
* Application class writing unexpected exceptions to a crash file before crashing.
*/
public class MyApplication extends Application {
private static final String TAG = "ExceptionHandler";
@Override
public void onCreate() {
super.onCreate();
// Setup handler for uncaught exceptions.
final Thread.UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable e) {
try {
handleUncaughtException(e);
System.exit(1);
} catch (Throwable e2) {
Log.e(TAG, "Exception in custom exception handler", e2);
defaultHandler.uncaughtException(thread, e);
}
}
});
}
private void handleUncaughtException(Throwable e) throws IOException {
Log.e(TAG, "Uncaught exception logged to local file", e);
// Create a new unique file
final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.US);
String timestamp;
File file = null;
while (file == null || file.exists()) {
timestamp = dateFormat.format(new Date());
file = new File(getFilesDir(), "crashLog_" + timestamp + ".txt");
}
Log.i(TAG, "Trying to create log file " + file.getPath());
file.createNewFile();
// Write the stacktrace to the file
FileWriter writer = null;
try {
writer = new FileWriter(file, true);
for (StackTraceElement element : e.getStackTrace()) {
writer.write(element.toString());
}
} finally {
if (writer != null) writer.close();
}
// You can (and probably should) also display a dialog to notify the user
}
}
次に、このApplicationクラスをAndroidManifest.xmlに登録します。
<application android:name="de.ioxp.arkmobile.MyApplication" >