第13章 综合技术
2016-03-02 16:32
736 查看
使用CrashHandler来获取crash信息;
当程序crash时,会调用CrashHandler的uncaughtException方法,在这个方法中获取crash信息并上传服务器来监控。import java.io.BufferedWriter;import java.io.File;
使用的时候,在application代码里。
使用multidex来解决方法数越界;
应用的方法数不能超过65536,通过将一个dex文件拆分多个dex文件来避免dex文件方法数越界问题。
android5.0以前引入google提供的android-support-multidex.jar,这个jar在SDK的extras/android/multidex/library/libs。
5.0以后默认支持,在AS里面使用。
配置app的build.gradle文件
defaultConfig添加
dependencies添加依赖
最后一步,代码中加入支持multidex功能
三种方法
1、manifest文件指定Application为MultiDexApplication
2、Application继承MultiDexApplication
3、Application不继承MultiDexApplication,重写Application的attachBaseContext方法。
指定放在主dex,在build.gradle中添加afterEvaluate,并要写maindexlist.txt文件。multidex的jar包的几个类必须打包到主dex。
动态加载
开源插件化框架DL:
GItHub:https://github.com/singwhatiwanna/dynamic-load-apk
/article/1603770.html
解决基础性问题:资源访问、Activity生命周期管理、ClassLoader管理。
反编译
dex2jjar将apk转称一个jar,jar再通过jd-gui打开能看到java代码,Apktool用于应用的解包和二次打包。
当程序crash时,会调用CrashHandler的uncaughtException方法,在这个方法中获取crash信息并上传服务器来监控。import java.io.BufferedWriter;import java.io.File;
import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.lang.Thread.UncaughtExceptionHandler; import java.text.SimpleDateFormat; import java.util.Date; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Build; import android.os.Environment; import android.os.Process; import android.util.Log; publicclassCrashHandlerimplementsUncaughtExceptionHandler{ privatestaticfinalString TAG ="CrashHandler"; privatestaticfinalboolean DEBUG =true; privatestaticfinalString PATH =Environment.getExternalStorageDirectory().getPath()+"/CrashTest/log/"; privatestaticfinalString FILE_NAME ="crash"; privatestaticfinalString FILE_NAME_SUFFIX =".trace"; privatestaticCrashHandler sInstance =newCrashHandler(); privateUncaughtExceptionHandler mDefaultCrashHandler; privateContext mContext; privateCrashHandler(){ } publicstaticCrashHandler getInstance(){ return sInstance; } public void init(Context context){ mDefaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this);//设置为线程默认的异常处理器 mContext = context.getApplicationContext(); } /** * 这个是最关键的函数,当程序中有未被捕获的异常,系统将会自动调用 #uncaughtException方法 * thread为出现未捕获异常的线程,ex为未捕获的异常,有了这个ex, 我们就可以得到异常信息。 */ @Override publicvoid uncaughtException(Thread thread,Throwable ex){ try{ //导出异常信息到SD卡中 dumpExceptionToSDCard(ex); uploadExceptionToServer(); //这里可以通过网络上传异常信息到服务器,便于开发人员分析日志从 而解决bug }catch(IOException e){ e.printStackTrace(); } ex.printStackTrace(); //如果系统提供了默认的异常处理器,则交给系统去结束我们的程序,否则就由我们自己结束自己 if(mDefaultCrashHandler !=null){ mDefaultCrashHandler.uncaughtException(thread, ex); }else{ Process.killProcess(Process.myPid()); } } privatevoid dumpExceptionToSDCard(Throwable ex)throwsIOException{ //如果SD卡不存在或无法使用,则无法把异常信息写入SD卡 if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ if(DEBUG){ Log.w(TAG,"sdcard unmounted,skip dump exception"); return; } } File dir =newFile(PATH); if(!dir.exists()){ dir.mkdirs(); } long current =System.currentTimeMillis(); String time =newSimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(newDate(current)); File file =newFile(PATH + FILE_NAME + time + FILE_NAME_SUFFIX); try{ PrintWriter pw =newPrintWriter(newBufferedWriter(newFileWriter(file))); pw.println(time); dumpPhoneInfo(pw); pw.println(); ex.printStackTrace(pw); pw.close(); }catch(Exception e){ Log.e(TAG,"dump crash info failed"); } } privatevoid dumpPhoneInfo(PrintWriter pw)throwsNameNotFoundException{ PackageManager pm = mContext.getPackageManager(); PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(),PackageManager.GET_ACTIVITIES); pw.print("App Version: "); pw.print(pi.versionName); pw.print('_'); pw.println(pi.versionCode); //android版本号 pw.print("OS Version: "); pw.print(Build.VERSION.RELEASE); pw.print("_"); pw.println(Build.VERSION.SDK_INT); //手机制造商 pw.print("Vendor: "); pw.println(Build.MANUFACTURER); //手机型号 pw.print("Model: "); pw.println(Build.MODEL); //cpu架构 pw.print("CPU ABI: "); pw.println(Build.CPU_ABI); } privatevoid uploadExceptionToServer(){ //TODO Upload Exception Message To Your Web Server } }
使用的时候,在application代码里。
//在这里为应用设置异常处理程序,然后我们的程序才能捕获未处理的异常 CrashHandler crashHandler =CrashHandler.getInstance(); crashHandler.init(this);
使用multidex来解决方法数越界;
应用的方法数不能超过65536,通过将一个dex文件拆分多个dex文件来避免dex文件方法数越界问题。
android5.0以前引入google提供的android-support-multidex.jar,这个jar在SDK的extras/android/multidex/library/libs。
5.0以后默认支持,在AS里面使用。
配置app的build.gradle文件
defaultConfig添加
//enable muitidex support multiDexEnabled true
dependencies添加依赖
compile 'com.android.support:multidex:1.0.0'
最后一步,代码中加入支持multidex功能
三种方法
1、manifest文件指定Application为MultiDexApplication
<application android:name="android.support.multidex.MultiDexApplication"
2、Application继承MultiDexApplication
3、Application不继承MultiDexApplication,重写Application的attachBaseContext方法。
@override protectedvoid attachBaseContext(Context base){ super.attachBaseContext(base); MultiDex.install(this); }
指定放在主dex,在build.gradle中添加afterEvaluate,并要写maindexlist.txt文件。multidex的jar包的几个类必须打包到主dex。
android/support/multidex/MultiDex.class android/support/multidex/MultiDexApplication.class android/support/multidex/MultiDexExtractor.class android/support/multidex/MultiDexExtractor$1.class android/support/multidex/MultiDex$V4.class android/support/multidex/MultiDex$V14.class android/support/multidex/MultiDex$V19.class android/support/multidex/ZipUtil.class android/support/multidex/ZipUtil$CentralDirectory.class afterEvaluate{ println "afterEvaluate" tasks.matching{ it.name.startsWith('dex') }.each{de-> def listFile = project.rootDir.absolutePath +'/app/maindexlist.txt' println "root dir:"+ project.rootDir.absolutePath println "dex task found:"+de.name if(dx.additionalParameters ==null){ de.additionParameters=[] } de.additionParameters +='--multi-dex'//当方法数越界时则生成多个dex文件 de.additionParameters +='--main-dex-list='+listFile //指定了要在主dex中打包的类列表 de.additionParameters +='--minimal-main-dex'//只有main-dex-list所指定的类才能打包到主dex中 } }
动态加载
开源插件化框架DL:
GItHub:https://github.com/singwhatiwanna/dynamic-load-apk
/article/1603770.html
解决基础性问题:资源访问、Activity生命周期管理、ClassLoader管理。
反编译
dex2jjar将apk转称一个jar,jar再通过jd-gui打开能看到java代码,Apktool用于应用的解包和二次打包。
相关文章推荐
- rsync使用时的常见报错问题解决解释
- Poj 2299 Ultra-QuickSort【逆序数】
- 如何查看android.jar中的xml文件
- 【AOP系列】(四)—采用Spring的静态配置文件实现AOP
- 74.Which statements are true regarding single row functions? (Choose all that apply.)
- 【Linux】——搭建redis
- 新学期对软件工程这门课程的看法
- IOS--Operation Object基础
- Spring IOC的配置使用(转)
- ASP.NET Web API 简介
- Iptables之FORWARD转发链
- DataTable常用方法属性
- ffmpeg的php扩展 在64位系统下的安装
- Spring事务管理之HibernateTransactionManager
- MySql
- UE3 Animation Compression Technical Guide
- 多进程通信
- 使用手机号登录、注册、重置密码
- 【Android】不弹root请求框检测手机是否root
- 《tar命令打包格式及组合find应用原理及误区详解》