一、概述

android应用捕捉所有线程没有catch的exception,并将相关日志文件压缩并发送到服务器。环境如下:
android: slf4j+logback,retrofit
server: play framework 2

二、自定义Application

public class MyApp extends Application {    private static final Logger log = LoggerFactory.getLogger(MyApp.class);    public boolean isUIThread(){        return Looper.getMainLooper().getThread() == Thread.currentThread();    }        @Override    public void onCreate() {        log.debug("onCreate");        super.onCreate();        //处理非捕捉异常        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {            @Override            public void uncaughtException(Thread thread, Throwable e) {                handleUncaughtException(thread, e);            }        });    }    private void handleUncaughtException(Thread thread, Throwable e) {        log.error("UncaughtException thread=" + thread.getName(), e);        if(isUIThread()) {//UI thread throw exception            invokeLogActivity();        }else{//non UI thread throw exception            new Handler(Looper.getMainLooper()).post(new Runnable() {                @Override                public void run() {                    invokeLogActivity();                }            });        }    }    //启动另外一个acitivy发送日志    private void invokeLogActivity(){        Intent intent = new Intent();        intent.setAction("cn.mydomain.SEND_LOG");        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);         startActivity(intent);        System.exit(1);    }}

三、发送错误日志文件的Activity

<activity  android:label="@string/base_warning" android:name=".ui.SendErrorLogActivity" android:theme="@android:style/Theme.Holo.Dialog" >    <intent-filter>        <action android:name="cn.mydomain.SEND_LOG" />        <category android:name="android.intent.category.DEFAULT" />    </intent-filter></activity>
public class SendErrorLogActivity extends Activity{    private static final Logger log = LoggerFactory.getLogger(SendErrorLogActivity.class);    private Button button;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setFinishOnTouchOutside(false);        LinearLayout layout = new LinearLayout(this);        layout.setOrientation(LinearLayout.VERTICAL);        layout.setPadding(8, 8, 8, 8);        layout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));        TextView textView = new TextView(this);        textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));        textView.setText(R.string.error_exit);        textView.setTextAppearance(this, R.style.TextAppearance_AppCompat_Large);        textView.setPadding(8, 8, 8, 8);        layout.addView(textView);        button = new Button(this);        button.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));        button.setText(R.string.base_confirm);        button.setGravity(Gravity.CENTER);        button.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                log.info("send error file to server");                try {                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM_dd_hh_mm_ss");                    String targetFile = getCacheDir() + "/errorMsg" + sdf.format(new Date()) + ".gz";                                   CompressUtil.createGzFile(MyApp.instance.getAppDir() + "/files/log.txt", targetFile);//压缩文件                    button.setEnabled(false);                    //发送文件到服务器                    MainManage.uploadErrorFile(new File(targetFile), new Function() {                        @Override                        public void success(Object o) {                            log.error("send error file success");                            log.error("app exit by uncaught exception");                            System.exit(1);                        }                        @Override                        public void fail(Throwable t) {                            log.error("send error file fail", t);                            log.error("app exit by uncaught exception");                            System.exit(1);                        }                    });                } catch (Exception e1) {                    log.error("send error file fail", e1);                    log.error("app exit by uncaught exception");                    System.exit(1);                }            }        });        layout.addView(button);        setContentView(layout);    }    @Override    public boolean onKeyDown(int keyCode, KeyEvent event) {        if (keyCode == KeyEvent.KEYCODE_BACK) {            log.error("app exit by uncaught exception without send error file");            System.exit(1);            return true;        }        return super.onKeyDown(keyCode, event);    }}

MainManage调用核心方法

    public static void uploadErrorFile(File file, final Function callback){        log.info("uploadErrorFile");        service.uploadErrorFile(new TypedFile("application/x-gzip", file), new MyCallBack("uploadErrorFile fileName=" + file.getName(), callback));    }    public interface MyService{        @Multipart        @POST("/app/errorFile")        void uploadErrorFile(@Part("errorFile") TypedFile errorFile, Callback<Response> cb);    }

四、服务器处理

routes

POST    /app/errorFile  cn.mydomain.web.controllers.Controller.uploadErrorFile()
    public Result uploadErrorFile(){        Http.MultipartFormData body = request().body().asMultipartFormData();        if(body == null){            return badRequest();        }        Http.MultipartFormData.FilePart errorFile = body.getFile("errorFile");        if (errorFile != null) {            String fileName = errorFile.getFilename();            logger.info("uploadErrorFile fileName=" + fileName);            File file = errorFile.getFile();            File targetDir = new File(GlobalData.ERROR_FILE_PATH);            if(!targetDir.exists()){                targetDir.mkdirs();            }            try {                IOUtils.copy(new FileInputStream(file), new FileOutputStream(GlobalData.ERROR_FILE_PATH + fileName));            } catch (IOException e) {                logger.error("upload error file fail filename=" + fileName, e);            }            return ok("File uploaded");        } else {            return badRequest();        }    }

版权声明:本文为博主原创文章,未经博主允许不得转载。

更多相关文章

  1. android之HttpURLConnection
  2. android 中调用接口发送短信
  3. Android(安卓)SDK 在线更新镜像服务器资源
  4. Android(安卓)系统应用调用,intent 的使用方法总结
  5. Android发送短信
  6. Android(安卓)发邮件
  7. Android(安卓)短信发送监控
  8. Android(安卓)客户端与服务器交互方式
  9. android客户端与服务器数据交换原则

随机推荐

  1. - Android深入浅出Binder机制
  2. Android(安卓)Studio快捷键(3) 代码提示
  3. Android命令生成编译出build.xml文件
  4. Android非正常结束时的生命周期
  5. XE5 Android(安卓)开发实现手机打电话和
  6. Android中获取字符串长度、宽度(所占像素
  7. Android:webView加载h5网页视频,播放不了,以
  8. android 桌面组件 App widget的使用
  9. 解决平台apk签名错误:no conscrypt_openjd
  10. Android基础教程之-----访Iphone 拖动相