上一篇博客传送门:Android常见问题总结(五)
26.如何处理Android 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
// 设置能否缓存图片信息(drawing cache)
view.setDrawingCacheEnabled(true);
// 如果能够缓存图片,则创建图片缓存
view.buildDrawingCache();
// 如果图片已经缓存,返回一个bitmap
Bitmap bitmap = view.getDrawingCache();
// 释放缓存占用的资源
view.destroyDrawingCache();
28.library 与 app资源同名冲突问题
29.Android 扬声器与听筒切换
- isSpeakerphoneOn:用于检测当前是否开启了扬声器
- setSpeakerphoneOn:设置是否打开扬声器
- 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" />
30.关于addView后宽高的一些细节
对于ViewGroup#addView方法,我们应该都不陌生,该方法经常可以用来动态添加子View- 在使用LayoutInflater时,传入父ViewGroup:LayoutInflater只有当我们传入父ViewGroup时,才会为我们解析的View设置正确的LayoutParams,否则其实我们写在xml上的布局信息并不会准确的生效
- 在addView之前,调用setLayoutParams设置
- 调用addView带有LayoutParams参数的方法
public void addView(View child) {
addView(child, -1);
}
public void addView(View child, int index) {
if (child == null) {
throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");
}
LayoutParams params = child.getLayoutParams();
if (params == null) {
params = generateDefaultLayoutParams();
if (params == null) {
throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null");
}
}
addView(child, index, params);
}
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}
从第11行我们可以看出,如果我们动态添加的View并没有设置好相应的LayoutParams,系统变会填充上一个默认的LayoutParams,而大多数情况下,这个LayoutParams的布局方式并不是我们想要的