欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android开发艺术探索小总结

程序员文章站 2022-06-28 09:57:08
1. IPC机制 组件在androidmenifest中指定androidprocess来创建多进程shareduid线程id">1.1四大组件在AndroidMenifes...

1. IPC机制

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的一些特殊操作

获取方式: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;
Android开发艺术探索小总结

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方法会被调用
Android开发艺术探索小总结

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特有的数据结构,适当使用弱引用和软引用,采用缓存策略等