Android开发艺术探索小总结

xiaoxiao2021-03-01  21

1. IPC机制

1.1四大组件在AndroidMenifest中指定android:process来创建多进程、sharedUID(线程ID)
1.2多进程的问题

1.2.1 静态成员和单例模式完全失效 1.2.2 线程同步机制失效 1.2.3 SharedPreferences的可靠性下降 1.2.4 Application会多次创建

1.3多进程通信方式

Intent、共享文件、基于Binder的Message、AIDL、Socket等

1.4数据序列化及Binder

1.4.1 Serializable接口 例如: bean继承Serializable接口 然后序列化: Bean bean = new Bean(,); ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(“test.txt”)); out.writeObject(bean); out.close(); 反序列化: ObjectInputStream in = new ObjectInputStream(new FileInputStream(“test.txt”)); Bean bean = (Bean)in.readObject(); In.close(); 1.4.2 Parcelable接口 例如: bean继承Parcelable接口,并且实现内部序列化、反序列化 序列化用内部的writeToParcel来实现 反序列化用内部的CREATOR并通过Parcel的一系列read方法来完成反序列化 1.4.3 Binder是ServiceManager链接各种Manager和相应的ManagerService的桥梁,主要用于Service中。

2. View的一些特殊操作

2.1 TouchSlop系统识别被认为滑动的最小距离

获取方式:ViewConfiguration.get(getContext()).getScledTouchSlop().

2.2 VelocityTracker速度追踪

获取方式:VelocityTracker vt = VelocityTracker.obtain(); vt.addMovement(event); vt.computCurrentVelocity(1000);//一段时间内手指划过的像素数,举例子1000ms int xVelocity = (int)vt.getXVelocity();//注意速度可以为负数 int yVelocity = (int)vt.getYVelocity(); vt.clear(); vt.recycle();//回收

2.3 手势检测GestureDetector

获取方式:GestrueDetector gd = new GestrueDetector(this); gd.setIsLongpressEnabled(false);//解决长按屏幕无法拖动 boolean consume =gd.OnTouchEvent(event);//接管目标View的OnTouchEvent方法 return consume;

2.4 动画库nineoldandroids
2.5 RemoteViews(跨进程更新界面,使用场景:通知栏和桌面小部件)

它的各种set方法设置样式

3 Android的Drawable

3.1 BitmapDrawable 对应标签 bitmap

表示一张图片,可以直接引用原始图片,也可以用xml描述

3.2 ShapeDrawable对应标签 shape

android:shape代表形状,属性有rectangle(矩形)、oval(椭圆)、line(横线)、ring(圆环); corners表示四个角的角度只适用于矩形shape gradient表示渐变效果 solid表示纯色填充 stroke表示描边 padding表示内部空白 size表示shape的宽高

3.3 LayerDrawable 对应标签layer-list–item

表示 层次的Drawable集合,类似于ps图层

3.4 StateListDrawable 对应标签selector

一般按钮点击状态

3.5 LevelListDrawable 对应标签level-list–item

表示 有等级的Drawable集合,根据不同等级切换对应的Drawable

3.6 TransitionDrawable 对应标签transition–item

表示两个Drawable淡入淡出的效果

3.7 InsetDrawable 对应的标签inset

表示可以将其他的Drawable内嵌到自己当中

3.8 ScaleDrawable 对应标签scale

表示根据自己的等级缩放到一定比例

3.9 ClipDrawable 对应标签clip

表示根据自己的等级裁剪另一个Drawable

4 消息机制

4.1 Handler的几个概念

4.1.1 MessageQueue消息队列,以队列的形式插入和删除,实际采用单链表的数据结构来存储消息队列;enqueueMessage方法是插入消息;next方法是取出消息 4.1.2 Looper 循环,MessageQueue存储数据,Looper有新消息就处理消息,没有就一直阻塞;其中 Looper的prepare方法创建Looper对象;Looper.getMainLooper在任何地方得到主线程的Looper;quit直接退出;quitSafely消息处理完退出;注意子线程中创建Looper,消息处理完后,一定要quit;loop方法调用后消息系统才起作用,它就是一个死循环,只有MessageQueue的next返回null的时候会跳出 4.1.3 ThreadLocal作用是在每个线程中存储数据,可以再不同线程中互不干扰的的存储并提供数据,通过ThreadLocal可以轻松的获取每个线程的Looper,主线程ActivityThread被创建时就初始化Looper。 4.1.4运行机制:Handler的send调用,它调用MessageQueue的enqueueMessage方法将消息放入消息队列中,然后Loop方法会调用MessageQueue的next方法来获取新消息,然后Looper去处理(最终是交给了Handler的对象的dispatchMessage方法),最终消息中的Runnable或者Handler的HandlerMessage方法会被调用

5线程和线程池

5.1线程

主线程处理与界面相关操作,子线程处理耗时操作。常见线程有IntentServer、HandlerThread、Thread等

5.2线程池AsyncTask 它封装了Handler和Thread

5.2.1AsyncTask是一个泛型类有三个参数:Params(表示参数的类型)、Progress(表示后台任务执行进度的类型)、Result(后台任务返回结果类型),如果不需要传递参数,可以用Void代替 5.2.2核心方法 (1)onPreExecute():在主线程中执行,在异步任务之前,会被调用 (2)doInBackground(Params…params):在线程池中执行,用于执行异步任务,params表示异步任务输入参数,在此方法中可以通过publishProgress方法更新进度,publishProgress会调用onProgressUpdate方法,并将返回结果传递给onPostExecute. (3)onProgressUpdate(Progress…values):在主线程中执行,当后台任务执行进度发生改变时会被调用 (4)onPostExecute(Result result)在主线程中执行,在异步执行之后会被调用,result是后台返回值,即(2)中返回的值 (5)onCancelled()在主线程中 执行,异步任务被取消的时候被调用,此时onPostExecute不会被调用 5.2.3 AsyncTask有两个线程池和一个Handler SerialExecutor可以分析AsyncTask的排队执行过程; THREAD_POOL_EXECUTOR用于执行任务; IntentHandler用于将执行环境充线程池切换到主线程; 核心线程数等于CPU核心数+1; 线程池最大线程数CPU核心数*2+1;

5.3线程池ThreadPoolExecutor

5.3.1优点 重用线程,减少开销;控制最大并发,防止阻塞 5.3.2分类(创建ExecutorService x=Executors.newXXXThreadPool) (1)FixedThreadPool:固定线程数的线程池,只有核心线程并且不会被回收,没有超时限制; (2)CacheThreadPool:线程数量不固定的线程池,有超时限制,60秒闲置会被回收; (3)ScheduleThreadPool:核心线程数固定,非核心线程没有限制,当非核心限制时就会回收; (4)SingleThreadPool:只有一个核心线程,所有任务在这一个线程中顺序执行;

6 Bitmap

6.1加载方法

BitmapFactory加载图四个方法decodeFile、decodeResource、decodeStream、decodeByteArray BitmapFactory.Options来缩放图片,主要使用inSampleSize参数,即采样率;还有inJustDecodeBounds参数,当它为true时只解析图片信息(宽高),不加载图片。

6.2缓存策略(Lru是Least Recently Used最近最少使用算法)

核心思想:当缓存快满时,会淘汰近期最少使用的缓存 LruCache(是一个泛型,内部使用 LinkedHashMap以强引用的方式存储对象) DiskLruCache(磁盘缓存 利用open方法来创建,一般存在应用的cache目录,内部使用Editor来操作数据)

7综合技术

7.1当出现crash时,会调用CrashHandler的uncaughtException方法,在这个方法里我们可以获取crash的信息。
7.2对于方法个数的限制(整个应用不超过65536个方法),可以使用Google的multidex的方案;也可以动态加载dex

8.JNI和NDK

8.1JNI(Java Native Interface java本地接口)

操作步骤: (1) java中声明native方法,并加载so库static{System.loadLibrary(“jni-test”);} (2) 编译Java源文件得到class,然后通过javah命令导出JNI的头文件 (3) 实现JNI方法(主目录新建jni文件夹放入(2)中生成的.h文件,然后用C++或者C实现方法) (4) 编译so库并在java中调用(so库编译用gcc,切换到jni目录,对于C++编译命令 C++:gcc -shared -I /usr/lib/jvm/java-7-openjdk-amd64/include -fPIC test.cpp -o libjni-test.so C:gcc -shared -I /usr/lib/jvm/java-7-openjdk-amd64/include -fPIC test.c -o libjni-test.so) 其中/usr/lib/jvm/java-7-openjdk-amd64是JDK的路径;

8.2NDK

操作步骤: (1) 下载并配置NDK,配置路径 (2) 创建Android项目,声明所需native方法并加载so库 (3) 实现声明的native方法,创建jni文件目录下创建三个文件:test.cpp、Android.mk和Application.mk。其中Android.mk中LOCAL_MODULE表示模块名称,LOCAL_SRC_FILES表示参与编译的源文件;Application.mk中APP_ABI表示CPU的架构平台类型(常见有armeabi、x86、mips) (4) 切换到jni目录的父目录,利用ndk-build命令生成so库 (5) 在app/src/main中创建jniLibs目录,将so复制进去,运行即可

9性能优化

9.1布局优化

尽量减少布局文件的层级,优先等级LinearLayout和FrameLayout比RelativeLayout简单 标签include、merge(减少层级)、ViewStub(按需加载)

9.2绘制优化

OnDraw中不要创建局部对象、不要做耗时任务

9.3内存泄漏

(1)静态变量持有activity不能释放 (2)单例模式对象持有activity不能释放 (3)属性动画一定要在onDestory中停止

9.4其他优化

(1)响应速度,主要主线程中做些耗时任务 (2)ListView和Bitmap优化 (3)线程优化,要是可以尽量使用线程池 (4)不要使用过多的枚举,使用一些Android特有的数据结构,适当使用弱引用和软引用,采用缓存策略等

转自:https://blog.csdn.net/Bingsman/article/details/78263421

转载请注明原文地址: https://www.6miu.com/read-3450284.html

最新回复(0)