Android常见问题总结(六)

来源:互联网 发布:淘宝蓝冠和钻石哪个好 编辑:程序博客网 时间:2024/05/16 14:12

上一篇博客传送门:Android常见问题总结(五)

26.如何处理Android Crash 并重启手机

一般而言,发生了APP Crash是由于我们的程序抛出了我们未捕获的RuntimeException
在Java中,我们可以通过setDefaultUncaughtExceptionHandler方法为某个线程设置默认未捕获异常处理器,当程序抛出未捕获异常时,会交由改处理器处理
Android的默认UncaughtExceptionHandler为弹出Dialog提醒用户APP Crash,并杀死进程退出程序
我们可以通过编写自己的UncaughtExceptionHandler来处理APP Crash的问题:
        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {            @Override            public void uncaughtException(Thread t, Throwable e) {                Intent intent = new Intent(MainActivity.this, MainActivity.class);                startActivity(intent);                Process.killProcess(Process.myPid());            }        });

下面例子中,点击按钮会抛出一个运行时异常,左图为未设置Handler之前,右图为设置Handler之后:



27.如何把view转化为bitmap

可以使用getDrawingCache方法:
// 设置能否缓存图片信息(drawing cache)view.setDrawingCacheEnabled(true);// 如果能够缓存图片,则创建图片缓存view.buildDrawingCache();// 如果图片已经缓存,返回一个bitmapBitmap bitmap = view.getDrawingCache();// 释放缓存占用的资源view.destroyDrawingCache();

28.library 与 app资源同名冲突问题

假设有以下场景:


在一个Project中有两个module,一个是应用app,另一个是android的library:mylibrary
两个module中存在着相同的资源名称

这种情况会导致什么问题呢?
会导致mylibrary module中的activity_main.xml被覆盖,无法获取

在网上查到的R类索引生成规则如下所示:

资源ID是一个4字节的无符号整数,其中,最高字节表示Package ID,次高字节表示Type ID,最低两字节表示Entry ID。        
Package ID相当于是一个命名空间,限定资源的来源。Android系统当前定义了两个资源命令空间,其中一个系统资源命令空间,它的Package ID等于0x01,另外一个是应用程序资源命令空间,它的Package ID等于0x7f。所有位于[0x01, 0x7f]之间的Package ID都是合法的,而在这个范围之外的都是非法的Package ID。前面提到的系统资源包package-export.apk的Package ID就等于0x01,而我们在应用程序中定义的资源的Package ID的值都等于0x7f,这一点可以通过生成的R.java文件来验证。        
Type ID是指资源的类型ID。资源的类型有animator、anim、color、drawable、layout、menu、raw、string和xml等等若干种,每一种都会被赋予一个ID。        
Entry ID是指每一个资源在其所属的资源类型中所出现的次序。注意,不同类型的资源的Entry ID有可能是相同的,但是由于它们的类型不同,我们仍然可以通过其资源ID来区别开来。

由于名称相同,两个module会对该资源生成相同的索引即(app.R.layout.activity_main == mylibrary.R.layout.activity_main)
如果app module依赖mylibrary module,那么最终生成的apk中所有的资源文件res和R类都会被集中到一起,也就是说mylibrary中的activity_main会被完全覆盖
原本在mylibrary module中的获取的activity_main资源均会变为app中的activity_main资源

stackoverflow对此问题给出的解决方案是:为你的android library资源添加相关的前缀,如AppCompat的前缀为abc_
https://stackoverflow.com/questions/42513509/is-there-any-way-in-android-module-to-pick-up-resources-from-its-own-module-and

29.Android 扬声器与听筒切换

要实现扬声器与听筒的切换.而android中实现对音量和振铃模式的控制主要通过AudioManager类来实现.

获取到AudioManager后,我们可以通过其几个关键的方法改变扬声器与听筒的状态:
  1. isSpeakerphoneOn:用于检测当前是否开启了扬声器
  2. setSpeakerphoneOn:设置是否打开扬声器
  3. setMode:设置音频模式,设置扬声器时,使用MODE_NORMAL,设置听筒时,使用MODE_IN_COMMUNICATION
具体实现如下:
    /**     * 设置是否开启扬声器     * @param isSpeakerOn 是否开启     */    public void setSpeakerphone(boolean isSpeakerOn) {        AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);        if (audioManager != null) {            audioManager.setMode(isSpeakerOn ? AudioManager.MODE_NORMAL : AudioManager.MODE_IN_COMMUNICATION);            audioManager.setSpeakerphoneOn(isSpeakerOn);        }    }

值得注意的是直接调用这个方法并不能切换生效,我们还需要申请MODIFY_AUDIO_SETTINGS的权限才行:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />


原创粉丝点击