一个Bitmap占用内存计算
即是通过占用的像素点多少和一个像素点占的字节数。一个像素用一串二进制表示。
即是宽高byte数。Bitmap.Config有一个属性决定这个字节数。分别为:
一个int值32位,占4个字节,那16位就占2字节,8位占1个字节
ALPHA_8 图片只有一个alpha透明度值,占8位 一个像素1字节
ARGB_4444 argb各占4位,共16位 一个像素2字节
RGB_565 没有alpha,rgb各占5,6,5位,共16位 一个像素2字节
ARGB_8888 argb各占8位,共32个字节 一个像素4字节
代码中可以用bitmap.getByteCount()获取当前这个占用的内存大小。
jpg为什么比png图片小?
jpg是有损压缩,png是无损压缩。jpg没有alpha值,png有。
动画实现原理:
Android视图是以树形结构添加的,子view都有一个父view。当一个view调用动画,会对其比如大小,位置,透明度等发生改变。子view就会在每一帧动画改变后调用invalidate(),invalidate内部获取了parentView-它的父view调用ondraw()进行重绘,父view就会遍历将所有子view进行重绘,从而将子view的变化过程实时绘制出来。
低版本SDK实现高版本api
当程序使用一些方法或属性时,当判断项目minsdk还不支持该属性时,就会报错。那么就要加上
@TargetApi(Build.VERSION_CODES.X),声明让低版本sdk去调用高版本的api。
Android为每个应用程序分配的内存大小是多少?
Android设备出厂以后,java虚拟机对单个应用的最大内存分配就确定下来了,一旦应用超出这个内存使用值就会OOM。
不同的手机支持的App最大内存不一样。可以通过ActivityManager去获取。
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
int memClass = activityManager.getMemoryClass();
Android应用程序的默认最大内存值为16M
static public int staticGetLargeMemoryClass() {
// Really brain dead right now -- just take this from the configured
// vm heap size, and assume it is in megabytes and thus ends with "m".
String vmHeapSize = SystemProperties.get("dalvik.vm.heapsize", "16m");
return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length() - 1));
}
Bundle机制
Bundle用于在Activity,fragment之间传值,Activity,fragment保存状态值的使用。
public final class Bundle extends BaseBundle implements Cloneable, Parcelable
Bundle用final修饰,不能被继承。由于要传值,所以需要序列化。
内部使用ArrayMap的键值对进行存储。
ArrayMap mMap = null;
什么情况需要使用多进程?
类似音乐类、跑步健身类、手机管家类等长时间需要在后台运行的应用。
需要当手机切到别的应用,锁屏的情况下,要让应用的核心功能继续运行,比如播放,计步数。
启动新进程开启服务,使服务进程可以使用的内存更多,更不容易被杀死。
怎么跨进程启动app?
使用PackageManager,通过包名来启动应用,intent需要添加flag FLAG_ACTIVITY_NEW_TASK。
这里启动一个应用,包名为com.libo.wanandroid,启动activity的类路径为com.libo.module_home.activity.HomeActivity:
/**
* 跨进程启动应用
*/
private void remoteLaunch() {
ComponentName componentName = new ComponentName("com.libo.wanandroid", "com.libo.module_home.activity.HomeActivity");
Intent launchIntent = new Intent();
launchIntent.setComponent(componentName);
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(launchIntent);
}
参考:https://blog.csdn.net/binzeefox/article/details/106755762
如何将一个Activity设置成窗口的样式。
简要描述一下AsynckTask的使用
AsyncTask抽象类,有三个泛型参数类型,第一个是你需要传递进来的参数类型,第二个是任务完成进度的类型一般是Integer,第三个是任务完成结果的返回类型,不需要的设为Void即可.
onPreExecute() doInbackground();子线程里执行 onPostExecute()返回执行结果
退出Activity或者退出App,那么后台任务不会立即退出,需要在onpause中调用cancle()方法
AsyncTask与Handler异步机制对比
1.AsyncTask是对Handler与Thread的封装。
2.AsyncTask底层是一个线程池,而Handler仅仅就是发送了一个消息队列。
View与SurfaceView、Textureview的区别:
surfaceView 是在一个新起的单独线程中可以重新绘制画面而 View 必须在 UI 的主线程中更新画面 ,SurfaceView类就是双缓冲机制。
Surfaceview是view子类,可用于视频播放,摄像头预览等;
SurfaceView不在View hierachy中,它的显示也不受View的属性控制,所以不能进行平移,缩放等变换;
SurfaceView双缓冲:
双缓冲:在运用时可以理解为:SurfaceView在更新视图时用到了两张Canvas,一张frontCanvas和一张backCanvas,每次实际显示的是frontCanvas,backCanvas存储的是上一次更改前的视图,当使用lockCanvas()获取画布时,得到的实际上是backCanvas而不是正在显示的frontCanvas,之后你在获取到的backCanvas上绘制新视图,再unlockCanvasAndPost(canvas)此视图,那么上传的这张canvas将替换原来的frontCanvas作为新的frontCanvas,原来的frontCanvas将切换到后台作为backCanvas。例如,如果你已经先后两次绘制了视图A和B,那么你再调用lockCanvas()获取视图,获得的将是A而不是正在显示的B,之后你将重绘的C视图上传,那么C将取代B作为新的frontCanvas显示在SurfaceView上,原来的B则转换为backCanvas。
Textureview与SurfaceView不同,它不会在WMS中单独创建窗口,而是作为View hierachy中的一个普通View,因此可以和其它普通View一样进行移动,旋转,缩放,动画等变化。
参考:https://blog.csdn.net/while0/article/details/81481771
Butterknife原理:在编译时发生,使用注解处理器生成对应类。
当你编译你的Android工程时,ButterKnife工程中ButterKnifeProcessor类的process()方法会执行以下操作:
开始它会扫描Java代码中所有的ButterKnife注解@Bind、@OnClick、@OnItemClicked等
当它发现一个类中含有任何一个注解时,ButterKnifeProcessor会帮你生成一个Java类,名字类似$$ViewBinder,这个新生成的类实现了ViewBinder接口
这个ViewBinder类中包含了所有对应的代码,比如@Bind注解对应findViewById(), @OnClick对应了view.setOnClickListener()等等。