수색…


NetworkOnMainThreadException

문서에서 :

응용 프로그램이 주 스레드에서 네트워킹 작업을 수행하려고 할 때 throw되는 예외입니다.

이는 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 입니다. 이로 인해 응용 프로그램이 시작되거나 실행되는 동안 응용 프로그램이 중지됩니다. 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로로드 할 때 일반적입니다.

몇 가지 옵션이 있습니다.

  1. 대규모 응용 프로그램 힙 사용

AndroidManifest.xml의 application 태그에 "largeHeap"옵션을 추가하십시오. 이렇게하면 앱에서 더 많은 메모리를 사용할 수 있지만 루트 문제를 해결하지는 못할 것입니다.

<application largeHeap="true" ... >
  1. 비트 맵을 재활용하십시오.

비트 맵을로드 한 후에는 재활용하고 메모리를 확보해야합니다.

    if (bitmap != null && !bitmap.isRecycled())
       bitmap.recycle();
  1. 샘플링 된 비트 맵을 메모리에로드

BitmapOptions 및 inSampleSize를 사용하여 축소 된 크기를 샘플링하여 메모리 전체에 한 번에 전체 비트 맵을로드하지 마십시오.

예를 들어 Android 설명서 를 참조하십시오.

DexException

com.android.dex.DexException: Multiple dex files define Lcom/example/lib/Class;

이 오류는 패키징 할 때 동일한 메소드 세트를 정의하는 두 개의 .dex 파일을 찾기 때문에 발생합니다.

보통 이것은 앱이 우연히 같은 라이브러리에 2 개의 독립된 의존성을 획득했기 때문에 발생합니다.

예를 들어, 프로젝트가 있고 AB 두 라이브러리에 의존하기를 원한다. AB 는 각각 자체 의존성을 갖는다. 라이브러리 B 이미 라이브러리 A 종속되어있는 경우 라이브러리 A 가 프로젝트 자체에 추가되면이 오류가 발생합니다. 라이브러리 B 컴파일하는 것은 이미 A 에서 코드 세트를 제공했기 때문에 컴파일러가 라이브러리 A 를 번들로 만들 때 이미 패키지 된 라이브러리 A 의 메소드를 찾습니다.


해결하려면 실수로 두 번 추가 할 수없는 종속성이 없는지 확인하십시오

UncaughtException

잡히지 않은 예외를 처리하려는 경우에는 onCreate 메서드에서 모두 catch하려고 시도하십시오. 응용 프로그램 클래스 :

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();
    }
}

예기치 않은 예외에 대한 자체 처리기 등록

이것은 시스템의 표준 "Application XYZ has crashed"과 유사하게 catch되지 않은 예외에 대응할 수있는 방법입니다.

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" >


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow