Android
Ausnahmen
Suche…
NetworkOnMainThreadException
Aus der Dokumentation :
Die Ausnahme, die ausgelöst wird, wenn eine Anwendung versucht, einen Netzwerkvorgang in ihrem Haupt-Thread auszuführen.
Dies wird nur für Anwendungen ausgelöst, die auf das Honeycomb SDK oder höher abzielen. Anwendungen, die auf frühere SDK-Versionen abzielen, dürfen in ihren Hauptereignisschleifen-Threads vernetzen, es wird jedoch dringend davon abgeraten.
Hier ist ein Beispiel eines Codefragments, das diese Ausnahme verursachen kann:
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);
}
}
}
}
}
Mit dem NetworkOnMainThreadException
Code wird NetworkOnMainThreadException
für Anwendungen NetworkOnMainThreadException
auf Honeycomb SDK (Android v3.0) oder höher abzielen, da die Anwendung versucht, eine Netzwerkoperation im Hauptthread auszuführen.
Um diese Ausnahme zu vermeiden, müssen Ihre Netzwerkvorgänge immer in einer Hintergrundtask über eine AsyncTask
, einen Thread
, einen IntentService
usw. ausgeführt werden.
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
Dies ist eine sehr häufige Exception
. Dadurch wird Ihre Anwendung während des Starts oder der Ausführung Ihrer App angehalten. Im LogCat
Sie die Meldung:
android.content.ActivityNotFoundException : Unable to find explicit activity class;
have you declared this activity in your AndroidManifest.xml?
Überprüfen Sie in diesem Fall, ob Sie Ihre Aktivität in der Datei AndroidManifest.xml
.
Die einfachste Möglichkeit, Ihre Activity
in AndroidManifest.xml
zu deklarieren, ist:
<activity android:name="com.yourdomain.YourStoppedActivity" />
Außerhalb des Speicherfehler
Dies ist ein Laufzeitfehler, der auftritt, wenn Sie eine große Menge Speicher auf dem Heap anfordern. Dies ist üblich, wenn eine Bitmap in eine ImageView geladen wird.
Sie haben einige Möglichkeiten:
- Verwenden Sie einen großen Anwendungshaufen
Fügen Sie dem Anwendungstag in Ihrer AndroidManifest.xml die Option "largeHeap" hinzu. Dadurch wird Ihrer App mehr Speicher zur Verfügung gestellt, das Root-Problem wird jedoch wahrscheinlich nicht behoben.
<application largeHeap="true" ... >
- Recyceln Sie Ihre Bitmaps
Stellen Sie nach dem Laden einer Bitmap sicher, dass Sie sie recyceln und Speicherplatz freigeben:
if (bitmap != null && !bitmap.isRecycled())
bitmap.recycle();
- Laden Sie abgetastete Bitmaps in den Speicher
Vermeiden Sie das gleichzeitige Laden der gesamten Bitmap in den Arbeitsspeicher, indem Sie eine reduzierte Größe mit BitmapOptions und inSampleSize abfragen.
Siehe beispielsweise die Android-Dokumentation
DexException
com.android.dex.DexException: Multiple dex files define Lcom/example/lib/Class;
Dieser Fehler tritt auf, weil die App beim .dex
zwei .dex
Dateien findet, die dieselbe Gruppe von Methoden definieren.
Normalerweise geschieht dies, weil die App versehentlich zwei separate Abhängigkeiten von derselben Bibliothek erworben hat.
Angenommen, Sie haben ein Projekt und möchten sich auf zwei Bibliotheken verlassen: A
und B
, die jeweils eigene Abhängigkeiten haben. Wenn Bibliothek B
bereits eine Abhängigkeit von Bibliothek A
, wird dieser Fehler ausgegeben, wenn Bibliothek A
von sich aus zum Projekt hinzugefügt wird. Beim Kompilieren der Bibliothek B
bereits der Code von A
. Wenn der Compiler die Bibliothek A
bündelt, werden die Methoden der Bibliothek A
bereits gepackt.
Stellen Sie zum Lösen sicher, dass keine Ihrer Abhängigkeiten auf diese Weise zweimal zufällig hinzugefügt werden konnte
Unbekannte Ausnahme
Wenn Sie nicht erfasste Ausnahmen behandeln möchten, versuchen Sie, sie alle in der onCreate-Methode Ihrer Application-Klasse abzufangen:
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();
}
}
Registrieren eines eigenen Handlers für unerwartete Ausnahmen
So können Sie auf Ausnahmen reagieren, die nicht erfasst wurden, ähnlich dem Standard des Systems "Anwendung XYZ ist abgestürzt".
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
}
}
Dann registrieren Sie diese Anwendungsklasse in Ihrer AndroidManifest.xml:
<application android:name="de.ioxp.arkmobile.MyApplication" >