Development Tip

내 Android 애플리케이션에서 충돌 데이터를 얻으려면 어떻게해야합니까?

yourdevel 2020. 9. 29. 18:47
반응형

내 Android 애플리케이션에서 충돌 데이터를 얻으려면 어떻게해야합니까?


Android 애플리케이션에서 크래시 데이터 (적어도 스택 추적)를 얻으려면 어떻게해야합니까? 적어도 케이블로 검색되는 내 자신의 장치에서 작업 할 때, 이상적으로는 야생에서 실행되는 내 응용 프로그램의 모든 인스턴스에서 작업하여 개선하고 더 견고하게 만들 수 있습니다.


ACRA (Android 용 애플리케이션 충돌 보고서) 라이브러리 사용해 볼 수 있습니다 .

ACRA는 Android 애플리케이션이 충돌 보고서를 GoogleDoc 양식에 자동으로 게시 할 수있는 라이브러리입니다. Android 애플리케이션 개발자가 충돌하거나 잘못 작동 할 때 애플리케이션에서 데이터를 가져 오는 데 도움을주기 위해 Android 애플리케이션 개발자를 대상으로합니다.

앱에 쉽게 설치할 수 있고 구성이 가능하며 어디에서나 서버 스크립트를 호스팅 할 필요가 없습니다. 보고서는 Google 문서 스프레드 시트로 전송됩니다!


샘플 애플리케이션 및 디버깅 목적으로 저는 스택 트레이스를 장치의 sd 카드에 기록하거나 서버에 업로드 할 수있는 간단한 솔루션을 사용합니다. 이 솔루션은 Project android-remote-stacktrace (특히 장치에 저장 및 서버에 업로드 부분)에서 영감을 얻었으며 Soonil이 언급 한 문제를 해결한다고 생각합니다. 최적은 아니지만 작동하며 프로덕션 애플리케이션에서 사용하려는 경우 개선 할 수 있습니다. 스택 트레이스를 서버에 업로드하기로 결정한 경우 php 스크립트 ( index.php)를 사용하여 볼 수 있습니다. 관심이 있으시면 아래의 모든 소스를 찾을 수 있습니다. 애플리케이션을위한 하나의 자바 클래스와 업로드 된 스택 트레이스를 호스팅하는 서버를위한 두 개의 선택적 php 스크립트입니다.

컨텍스트 (예 : 기본 활동)에서

if(!(Thread.getDefaultUncaughtExceptionHandler() instanceof CustomExceptionHandler)) {
    Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(
            "/sdcard/<desired_local_path>", "http://<desired_url>/upload.php"));
}

CustomExceptionHandler

public class CustomExceptionHandler implements UncaughtExceptionHandler {

    private UncaughtExceptionHandler defaultUEH;

    private String localPath;

    private String url;

    /* 
     * if any of the parameters is null, the respective functionality 
     * will not be used 
     */
    public CustomExceptionHandler(String localPath, String url) {
        this.localPath = localPath;
        this.url = url;
        this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
    }

    public void uncaughtException(Thread t, Throwable e) {
        String timestamp = TimestampFormatter.getInstance().getTimestamp();
        final Writer result = new StringWriter();
        final PrintWriter printWriter = new PrintWriter(result);
        e.printStackTrace(printWriter);
        String stacktrace = result.toString();
        printWriter.close();
        String filename = timestamp + ".stacktrace";

        if (localPath != null) {
            writeToFile(stacktrace, filename);
        }
        if (url != null) {
            sendToServer(stacktrace, filename);
        }

        defaultUEH.uncaughtException(t, e);
    }

    private void writeToFile(String stacktrace, String filename) {
        try {
            BufferedWriter bos = new BufferedWriter(new FileWriter(
                    localPath + "/" + filename));
            bos.write(stacktrace);
            bos.flush();
            bos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void sendToServer(String stacktrace, String filename) {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("filename", filename));
        nvps.add(new BasicNameValuePair("stacktrace", stacktrace));
        try {
            httpPost.setEntity(
                    new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
            httpClient.execute(httpPost);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

upload.php

<?php
    $filename = isset($_POST['filename']) ? $_POST['filename'] : "";
    $message = isset($_POST['stacktrace']) ? $_POST['stacktrace'] : "";
    if (!ereg('^[-a-zA-Z0-9_. ]+$', $filename) || $message == ""){
        die("This script is used to log debug data. Please send the "
                . "logging message and a filename as POST variables.");
    }
    file_put_contents($filename, $message . "\n", FILE_APPEND);
?>

index.php

<?php
    $myDirectory = opendir(".");
    while($entryName = readdir($myDirectory)) {
        $dirArray[] = $entryName;
    }
    closedir($myDirectory);
    $indexCount = count($dirArray);
    sort($dirArray);
    print("<TABLE border=1 cellpadding=5 cellspacing=0 \n");
    print("<TR><TH>Filename</TH><TH>Filetype</th><th>Filesize</TH></TR>\n");
    for($index=0; $index < $indexCount; $index++) {
        if ((substr("$dirArray[$index]", 0, 1) != ".") 
                && (strrpos("$dirArray[$index]", ".stacktrace") != false)){ 
            print("<TR><TD>");
            print("<a href=\"$dirArray[$index]\">$dirArray[$index]</a>");
            print("</TD><TD>");
            print(filetype($dirArray[$index]));
            print("</TD><TD>");
            print(filesize($dirArray[$index]));
            print("</TD></TR>\n");
        }
    }
    print("</TABLE>\n");
?>

BugSense 를 사용해 볼 수도 있습니다 . BugSense는 모든 충돌 보고서를 수집 및 분석하여 의미 있고 시각적 인 보고서를 제공합니다. 무료이며 통합을 위해 단 한 줄의 코드입니다.

면책 조항 : 저는 공동 설립자입니다.


Android 2.2에서는 이제 Android 마켓 애플리케이션에서 오류 보고서를 자동으로 가져올 수 있습니다.

Android 마켓 앱의 새로운 버그보고 기능을 사용하면 개발자가 사용자로부터 오류를 수신하고 보고서를 동결 할 수 있습니다. 보고서는 게시자 계정에 로그인 할 때 사용할 수 있습니다.

http://developer.android.com/sdk/android-2.2-highlights.html


을 사용하여 이러한 예외를 처리 할 수 Thread.setDefaultUncaughtExceptionHandler()있지만 이는 Android의 예외 처리 방법을 엉망으로 만드는 것처럼 보입니다. 나는 이런 성격의 핸들러를 사용하려고했다.

private class ExceptionHandler implements Thread.UncaughtExceptionHandler {
    @Override
    public void uncaughtException(Thread thread, Throwable ex){
        Log.e(Constants.TAG, "uncaught_exception_handler: uncaught exception in thread " + thread.getName(), ex);

        //hack to rethrow unchecked exceptions
        if(ex instanceof RuntimeException)
            throw (RuntimeException)ex;
        if(ex instanceof Error)
            throw (Error)ex;

        //this should really never happen
        Log.e(Constants.TAG, "uncaught_exception handler: unable to rethrow checked exception");
    }
}

그러나 예외를 다시 던져도 원하는 동작을 얻을 수 없었습니다. 즉, 예외를 로깅하면서 Android가 발생한 구성 요소를 종료하도록 허용했기 때문에 잠시 후 포기했습니다.


질문이 너무 오래되었다는 것을 알고 내 답변이 같은 문제를 가진 다른 사람들에게 도움이되기를 바랍니다.

부여 Crashlytics을 시도합니다. 응용 프로그램이있는 모든 장치의 모든 충돌에 대한 심층적 인 통찰력을 제공하고 이메일을 통해 알림을 보냅니다. 그리고 가장 좋은 부분은 완전히 무료로 사용할 수 있다는 것입니다 ..


좋아, rrainn과 Soonil에서 제공된 샘플을 살펴 보았고 오류 처리를 엉망으로 만들지 않는 솔루션을 찾았습니다.

CustomExceptionHandler를 수정하여 새 스레드와 연결된 스레드의 원래 UncaughtExceptionHandler를 저장했습니다. 새로운 "uncaughtException"-메서드의 끝에서 저장된 UncaughtExceptionHandler를 사용하여 이전 함수를 호출합니다.

DefaultExceptionHandler 클래스에는 sth가 필요합니다. 이렇게 :

public class DefaultExceptionHandler implements UncaughtExceptionHandler{
  private UncaughtExceptionHandler mDefaultExceptionHandler;

  //constructor
  public DefaultExceptionHandler(UncaughtExceptionHandler pDefaultExceptionHandler)
  {
       mDefaultExceptionHandler= pDefaultExceptionHandler;
  }
  public void uncaughtException(Thread t, Throwable e) {       
        //do some action like writing to file or upload somewhere         

        //call original handler  
        mStandardEH.uncaughtException(t, e);        

        // cleanup, don't know if really required
        t.getThreadGroup().destroy();
  }
}

http://code.google.com/p/android-remote-stacktrace 에서 코드를 수정 하면 현장에서 웹 서버 또는 sd-card에 로그인 할 수있는 좋은 작업 기반을 갖게됩니다.


저는 제 Android 및 iOS 앱에 Crittercism사용하고 있습니다. techcrunch 에서 이에 대해 들었습니다. 지금까지 그들과 꽤 만족합니다!


Google Play Developers Console은 실제로 충돌하여 보고서를 보낸 앱의 스택 추적을 제공합니다. 또한 정보를 확인하는 데 도움이되는 매우 좋은 차트도 있습니다 (아래 예 참조).

여기에 이미지 설명 입력


나는 여기에 내 자신의 버전을 만들었다 : http://androidblogger.blogspot.com/2009/12/how-to-improve-your-application-crash.html

기본적으로는 동일하지만 http 연결이 아닌 메일을 사용하여 보고서를 보내고 더 중요한 것은 애플리케이션 버전, OS 버전, 전화 모델 또는 사용 가능한 메모리와 같은 정보를 보고서에 추가했습니다. .


이것을 사용하여 예외 세부 정보를 포착하십시오.

String stackTrace = Log.getStackTraceString(exception); 

이것을 데이터베이스에 저장하고 로그를 유지하십시오.


라이브러리뿐 아니라 전체 (단순) 서비스를 사용할 수도 있습니다. 우리 회사는이를위한 서비스를 방금 출시했습니다 : http://apphance.com .

5 분 안에 추가하고 통합하는 간단한 .jar 라이브러리 (Android 용)가 있으며 라이브러리는 충돌 정보뿐만 아니라 실행중인 애플리케이션의 로그도 수집 할뿐만 아니라 테스터가 장치에서 직접 문제를보고 할 수 있습니다. 전체 컨텍스트 (WiFi에 연결되어 있는지 여부 등 기기 회전). 애플리케이션, 충돌, 로그, 통계 등의 세션을 추적 할 수있는 매우 훌륭하고 유용한 웹 패널을 사용하여 로그를 볼 수 있습니다. 이 서비스는 현재 비공개 베타 테스트 단계에 있지만 액세스를 요청할 수 있으며 매우 빠르게 제공합니다.

면책 조항 : 저는 Polidea의 CTO이자 서비스의 공동 제작자입니다.


Stackoverflow이 답변을 찾는 데 도움 이되는 리소스에 감사드립니다 .

원격 Android 충돌 보고서를 이메일에서 직접 찾을 수 있습니다 . CustomExceptionHandler 클래스 안에 이메일넣어야 한다는 것을 기억하십시오 .

public static String sendErrorLogsTo = "tushar.pandey@virtualxcellence.com" ;

필요한 단계 :

1st) 활동의 onCreate 에서이 코드 섹션을 사용하십시오.

    if(!(Thread.getDefaultUncaughtExceptionHandler() instanceof CustomExceptionHandler)) {
        Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(this));
    }   

2nd) 내 phpscript에 따라 (rrainn)의 CustomExceptionHandler 클래스의 재정의 된 버전을 사용하십시오.

package com.vxmobilecomm.activity;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.AsyncTask;
import android.util.Log;

public class CustomExceptionHandler implements UncaughtExceptionHandler {

    private UncaughtExceptionHandler defaultUEH;
    public static String sendErrorLogsTo = "tushar.pandey@virtualxcellence.com" ;

    Activity activity;

    public CustomExceptionHandler(Activity activity) {
        this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
        this.activity = activity;
    }

    public void uncaughtException(Thread t, Throwable e) {

        final Writer result = new StringWriter();
        final PrintWriter printWriter = new PrintWriter(result);
        e.printStackTrace(printWriter);
        String stacktrace = result.toString();
        printWriter.close();
        String filename = "error" + System.nanoTime() + ".stacktrace";

        Log.e("Hi", "url != null");
        sendToServer(stacktrace, filename);

        StackTraceElement[] arr = e.getStackTrace();
        String report = e.toString() + "\n\n";
        report += "--------- Stack trace ---------\n\n";
        for (int i = 0; i < arr.length; i++) {
            report += "    " + arr[i].toString() + "\n";
        }
        report += "-------------------------------\n\n";

        report += "--------- Cause ---------\n\n";
        Throwable cause = e.getCause();
        if (cause != null) {
            report += cause.toString() + "\n\n";
            arr = cause.getStackTrace();
            for (int i = 0; i < arr.length; i++) {
                report += "    " + arr[i].toString() + "\n";
            }
        }
        report += "-------------------------------\n\n";

        defaultUEH.uncaughtException(t, e);
    }

    private void sendToServer(String stacktrace, String filename) {
        AsyncTaskClass async = new AsyncTaskClass(stacktrace, filename,
                getAppLable(activity));
        async.execute("");
    }

    public String getAppLable(Context pContext) {
        PackageManager lPackageManager = pContext.getPackageManager();
        ApplicationInfo lApplicationInfo = null;
        try {
            lApplicationInfo = lPackageManager.getApplicationInfo(
                    pContext.getApplicationInfo().packageName, 0);
        } catch (final NameNotFoundException e) {
        }
        return (String) (lApplicationInfo != null ? lPackageManager
                .getApplicationLabel(lApplicationInfo) : "Unknown");
    }

    public class AsyncTaskClass extends AsyncTask<String, String, InputStream> {
        InputStream is = null;
        String stacktrace;
        final String filename;
        String applicationName;

        AsyncTaskClass(final String stacktrace, final String filename,
                String applicationName) {
            this.applicationName = applicationName;
            this.stacktrace = stacktrace;
            this.filename = filename;
        }

        @Override
        protected InputStream doInBackground(String... params) 
        { 
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(
                    "http://suo-yang.com/books/sendErrorLog/sendErrorLogs.php?");

            Log.i("Error", stacktrace);

            try {
                List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
                        6);

                nameValuePairs.add(new BasicNameValuePair("data", stacktrace));
                nameValuePairs.add(new BasicNameValuePair("to",sendErrorLogsTo));
                nameValuePairs.add(new BasicNameValuePair("subject",applicationName));

                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

                HttpResponse response = httpclient.execute(httppost);

                HttpEntity entity1 = response.getEntity();

                BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(
                        entity1);

                is = bufHttpEntity.getContent();

            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return is;
        }

        @Override
        protected void onPostExecute(InputStream result) {
            super.onPostExecute(result);

            Log.e("Stream Data", getStringFromInputStream(is));
        }
    }

    // convert InputStream to String
    private static String getStringFromInputStream(InputStream is) {

        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();

        String line;
        try {

            br = new BufferedReader(new InputStreamReader(is));
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return sb.toString();

    }
}

이것은 매우 무차별 적이지만 어디에서나 logcat을 실행할 수 있으므로 빠르고 더러운 해킹은 모든 catch 블록에 추가하는 것입니다. getRuntime().exec("logcat >> /sdcard/logcat.log");


fabric이라는 도구가 있습니다. 이것은 애플리케이션이 라이브로 배포되고 개발 중에 충돌 보고서를 얻을 수있는 충돌 분석 도구입니다. 이 도구를 애플리케이션에 추가하는 것도 간단합니다. 애플리케이션이 충돌 할 때 해당 충돌 보고서를 fabric.io 대시 보드에서 볼 수 있습니다. 보고서가 자동으로 포착되었습니다. 사용자에게 권한을 요청하지 않습니다. 버그 / 충돌 보고서를 보낼 것인지 여부. 그리고 이것은 완전히 무료입니다 ... https://get.fabric.io/


Google Firebase 는 휴대 전화에서 충돌 / 오류 데이터를 제공하는 Google의 최신 (2016) 방법입니다. build.gradle 파일에 포함하십시오.

compile 'com.google.firebase:firebase-crash:9.0.0'

치명적 충돌은 사용자 입력없이 자동으로 기록되며 치명적이지 않은 충돌 또는 다음과 같은 기타 이벤트도 기록 할 수 있습니다.

try
{

}
catch(Exception ex)
{
    FirebaseCrash.report(new Exception(ex.toString()));
}

이 페이지의 많은 답변이 유용하지만 구식이되기 쉽습니다. AppBrain 웹 사이트는 통계를 집계하여 현재 가장 인기있는 충돌보고 솔루션을 찾을 수 있습니다.

Android 충돌보고 라이브러리

앱 브레인 웹 사이트

이 사진을 게시 할 때 Crashlytics가 앱의 5.24 %와 설치의 12.38 %에서 사용되었음을 알 수 있습니다.


이제 며칠 동안 Firebase 오류 보고서가 매우 인기 있고 사용하기 쉽습니다. 자세한 내용은 다음 링크를 참조하십시오 : Firebase 오류보고

도움이되기를 바랍니다.


우리는 회사 내부에서 자체 개발 한 시스템을 사용하고 있으며 이는 우리에게 매우 유용합니다. 보고서를 수신하고 일부 분석을 수행하는 서버 및 서버에 충돌 보고서를 보내는 Android 라이브러리입니다. 서버는 예외 이름, 스택 추적, 메시지별로 예외를 그룹화합니다. 수정해야하는 가장 중요한 문제를 식별하는 데 도움이됩니다. 우리의 서비스는 현재 공개 베타 버전이므로 누구나 시도해 볼 수 있습니다. http://watchcat.co 에서 계정을 만들 거나 데모 액세스 http://watchcat.co/reports/index.php?demo를 사용하여 어떻게 작동하는지 살펴볼 수 있습니다 .


Sherlock 이라는 안드로이드 라이브러리가 있습니다 . 장치 및 응용 프로그램 정보와 함께 충돌에 대한 전체 보고서를 제공합니다. 충돌이 발생할 때마다 알림 표시 줄에 알림이 표시되고 알림을 클릭하면 충돌 세부 정보가 열립니다. 이메일이나 기타 공유 옵션을 통해 다른 사람과 충돌 세부 정보를 공유 할 수도 있습니다.

설치

android {
    dataBinding {
      enabled = true
    }
}

compile('com.github.ajitsing:sherlock:1.0.0@aar') {
    transitive = true
}

데모

여기에 이미지 설명 입력


즉시 답변을 원하면 logcat 을 사용할 수 있습니다.

$adb shell logcat -f /sdcard/logoutput.txt *:E

지금 로그에 정크가 너무 많으면 먼저 삭제 해보세요.

$adb shell logcat -c

그런 다음 앱을 실행 한 다음 다시 logcat을 시도하십시오.


오류 보고서를 추적 할 수있는 훌륭한 웹 애플리케이션이 하나 더 있습니다.

https://mint.splunk.com/

구성 할 단계가 적습니다.

  1. 위 링크를 사용하여 로그인하거나 가입하고 구성하십시오. 응용 프로그램 생성을 완료하면 아래와 같이 구성 할 줄이 제공됩니다.
Mint.initAndStartSession(YourActivity.this, "api_key");
  1. 애플리케이션의 build.gradl에 다음을 추가합니다.
android {
...
    repositories {
        maven { url "https://mint.splunk.com/gradle/"}
    }
...
}

dependencies {
...
    compile "com.splunk.mint:mint:4.4.0"
...
}
  1. 위에서 복사 한 코드를 추가하고 모든 활동에 추가하십시오.

    Mint.initAndStartSession (YourActivity.this, "api_key");

그게 다야. 로그인하고 애플리케이션 대시 보드로 이동하면 모든 오류 보고서를 받게됩니다.

누군가에게 도움이되기를 바랍니다.


대체 충돌보고 / 예외 추적 서비스를 확인하려면 Raygun.io를 확인 하십시오. 앱에 연결할 때 적절한 사용자 경험을 포함하여 Android 충돌을 처리하기위한 멋진 논리가 많이 있습니다 (주 활동에 두 줄의 코드와 몇 줄 AndroidManifest에 붙여 넣은 XML 행).

앱이 충돌하면 스택 추적, 하드 / 소프트웨어에 대한 환경 데이터, 사용자 추적 정보, 사용자가 지정한 모든 사용자 지정 데이터 등을 자동으로 가져옵니다. API에 비동기 적으로 게시하여 UI 스레드를 차단하지 않고 캐시합니다. 사용 가능한 네트워크가없는 경우 디스크에.

면책 조항 : Android 공급자를 구축했습니다. :)


Google Forms를 백엔드로 사용하여 ACRA https://github.com/ACRA/acra 를 사용하기 시작했으며 설정 및 사용이 매우 간단하며 기본값입니다.

그러나 Google 설문지로 보고서 보내기는 더 이상 사용되지 않습니다 (제거됨) : https://plus.google.com/118444843928759726538/posts/GTTgsrEQdN6 https://github.com/ACRA/acra/wiki/Notice-on-Google -양식-스프레드 시트-사용

어쨌든 자신의 발신자 https://github.com/ACRA/acra/wiki/AdvancedUsage#wiki-Implementing_your_own_sender 를 정의 할 수 있습니다. 예를 들어 발신자에게 이메일을 보낼 수 있습니다.

최소한의 노력으로 bugsense에 보고서를 보낼 수 있습니다. http://www.bugsense.com/docs/android#acra

NB Bugsense 무료 계정은 매월 500 개 보고서로 제한됩니다.


파티에 늦게 나는 ACRA가 무엇보다도 최선의 선택이라고지지하고 믿습니다. 설정 및 구성이 쉽습니다. ACRA를 사용하여 충돌 보고서를 가져오고 MandrillAp을 사용하여 내 이메일 주소로 동일한 메일을 보내기 위해 모든 곳에서 입력 한 세부 가이드를 만들었습니다.

게시물 링크 : https://androidician.wordpress.com/2015/03/29/sending-crash-reports-with-acra-over-email-using-mandrill/

github의 샘플 프로젝트 링크 : https://github.com/ayushhgoyal/AcraSample


저는 바로이 목적을 위해 디자인 한 Bugsnag 의 창립자 중 한 명입니다 . Bugsnag는 Android 앱에서 처리되지 않은 예외를 자동으로 캡처하여 대시 보드로 전송하여 수정 우선 순위를 지정하고 진단 정보를 살펴볼 수 있습니다.

다음은 일부 코드 스 니펫과 함께 오류보고 시스템을 선택하거나 구축 할 때 고려해야 할 몇 가지 중요한 사항입니다.

  • 처리되지 않은 예외를 자동으로 감지 ( 예제 코드 )
  • 메모리 사용량, 장치 정보 등과 같은 진단 데이터 수집 ( 예제 코드 )
  • 근본 원인별로 충돌을 효과적으로 그룹화
  • 재생산을 돕기 위해 각 충돌 전에 사용자가 취한 조치를 추적 할 수 있습니다 ( 예제 코드 ).

Android에서 크래시 처리 /보고와 관련된 몇 가지 모범 사례를 보려면 완전 오픈 소스 인 Bugsnag의 크래시보고 라이브러리에 대한 전체 소스 코드를 확인하고 자유롭게 분리하여 자신의 애플리케이션에서 사용할 수 있습니다!


앱이 다른 사람에 의해 다운로드되고 원격 장치에서 충돌하는 경우 Android 오류보고 라이브러리 ( 이 SO 게시물 에서 참조)를 살펴볼 수 있습니다 . 자신의 로컬 장치에만있는 경우 LogCat을 사용할 수 있습니다. 크래시가 발생했을 때 기기가 호스트 머신에 연결되어 있지 않더라도 기기를 연결하고 adb logcat 명령을 실행하면 전체 logcat 기록이 다운로드됩니다 (적어도 일반적으로 로그 데이터가 너무 많은 버퍼링되는 범위까지). , 그것은 무한하지 않습니다). 이러한 옵션 중 하나가 귀하의 질문에 답이됩니까? 그렇지 않다면 당신이 찾고있는 것을 조금 더 명확히 할 수 있습니까?


Flurry 분석 은 충돌 정보, 하드웨어 모델, Android 버전 및 라이브 앱 사용 통계를 제공합니다. 새 SDK에서는 더 자세한 충돌 정보 http://www.flurry.com/flurry-crash-analytics.html 을 제공하는 것 같습니다 .


Google은 실제로받는 오류 보고서의 양을 변경했습니다. 이전에는 수동으로보고 된 버그 보고서 만 받았습니다.

지난 개발자 컨퍼런스와 Android Vitals 소개 이후 진단 데이터를 공유 할 수있는 사용자로부터 충돌 보고서를 받게됩니다.

사용 및 진단 데이터를 자동으로 공유하도록 선택한 사용자의 Android 기기에서 수집 된 모든 비정상 종료가 표시됩니다. 지난 2 개월 동안의 데이터를 사용할 수 있습니다.

비정상 종료 및 애플리케이션 응답 없음 (ANR) 오류보기


Android Studio에서 직접이 작업을 수행 할 수 있습니다. 휴대 전화를 연결하고 앱을 실행 한 다음 충돌을 허용하면 Android Studio에서 직접 스택 추적을 볼 수 있습니다.

참고 URL : https://stackoverflow.com/questions/601503/how-do-i-obtain-crash-data-from-my-android-application

반응형