您的位置:首页 > 移动开发 > Android开发

安卓细节知识点流水账(一)

2017-08-15 17:22 330 查看

Activivy

手机跟用户交互的的界面

android 任务栈:后进先出

activity启动模式:

standard : 每次都会默认创建一个新的activity实例放入任务栈中

singleTop:栈顶复用模式。如果想创建的activity在任务栈栈顶,则使用栈顶的activity不重新创建

singleTask:如果想启动的activity存在于任务栈中,则将该activity置于栈顶,并将它上面的activity实例全部清除

singleInstance:activity实例独享一个任务栈

activity scheme跳转协议

android中scheme协议是一种内部跳转协议,

* 通过自定义scheme协议,可以非常方便地跳转app中的各个页面

* 通过自定义scheme协议 服务器可以定制化的告诉app要跳转到那个页面。

* 可以通过通知栏消息定制跳转页面

* 可以通过H5页面跳转页面

* APP通过scheme协议跳转到另一个APP中

Fragment

FragmentPagerAdapter和FragmentStatePagerAdapter 的区别 :

FragmentStatePagerAdapter

在切换不同的Fragment的时候,我们会把前面的Fragment销毁,而我们系统在销毁前,会把我们的我们Fragment的Bundle在我们的onSaveInstanceState(Bundle)保存下来。等用户切换回来的时候,我们的Fragment就会根据我们的instance state恢复出来。

FragmentPagerAdapter

Fragment在切换的时候,不会销毁,而只是调用事务中的detach方法,这种方法,我们只会把我们的Fragment的view销毁,而保留了以前的Fragment对象。所以通过这种方式创建的Fragment一直不会被销毁。

结论:

FragmentPagerAdapter 适用于页面较少的地方

FragmentStatePagerAdapter 适用于页面较多的地方

Service

启动方法:startService()和bindService

srartService()调用onStartCommand方法

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
return super.onStartCommand(intent, flags, startId);
}


onStartCommand()的返回值是int 有下面几种类型

(1)START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null

(2)START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务

(3)START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。

(4)START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

bindService()调用ServiceConnection()方法

mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
InterpttService.LocalBinder localBinder = (InterpttService.LocalBinder) service;
}

@Override
public void onServiceDisconnected(ComponentName name) {

}
};


IntentService

IntentService可以用来处理异步请求,其内部维护有子线程。启动方式跟传统的service的方式一样。当执行完任务之后它会自动停止。不需要手动去指定stopSelf()。IntentService可以启动多次,但是每次只会执行一个,剩下的都会进入队列中在IntentService的onHandleIntent方法中。当上一个执行完后再依次执行下一个。

Broadcast Receiver

跟观察者模式很像

可以在不同进程之间通信。同一个APP中的不同进程和不同的APP中都可以

内部实现机制

(1)自定义BroadcastReceiver的接收者 重写 onReceiver()方法

(2)通过Binder机制向AMS(Activity Manager Service)进行注册

(3)广播发送者通过Binder向AMS发送广播

(4)AMS查找符合条件的BroadcastReceiver的接收者,将广播发送到相应的消息队列中

(5)消息循环执行拿到此广播放回调到onReceiver()中。

WebView

(1)WebView的内存泄露。

解决方法:《1》另外单独开一个进程 去使用WebView 并且当这个 进程结束时,请手动调用System.exit(0)。《2》动态创建WebView。对WebView中使用的Context使用弱引用。

第一种方法比较好。

(2)onPageFinished()

这个方法的调用时机不够准确,哪里都可能调用。所以别用这个方法。实在想用可以使用onProgressChanged()代替。

(3)导致耗电。

《1》后台无法释放js 如果遇到这种情况 请在onstop和onresume里分别把setJavaScriptEnabled();

给设置成false和true。

《2》后台线程无法释放 。 暴力解决在onDestory()中调用System.exit(0)

Binder

进程间通信

* 被请求端(server)在ServiceManager中注册

* 请求端(client)请求的时候,ServiceManager查找需要请求的方法是否存在,如果存在将server的代理对象返回给client

* client通过server的代理对象的操控实现进程间的通信。

Handler(发送消息,处理消息)

handler 通过发送和处理Message和Runnable对象来关联相对应线程的MessageQueue。

handler创建的时候,如果不传入looper默认是当前线程的looper。

handler会从MessageQueue中不断的循环取出消息交给Message或Runnable处理。

handler 使用不当会造成内存泄露。

原因:匿名内部类会持有外部activity的引用,如果handler中执行了耗时操作,当activity销毁的时候,handler还在运行。造成内存泄露。

解决方法:将handler设置成静态类。内部持有activity的弱引用。

AsyncTask

本质:封装了线程池和handler的异步框架。

(1)一般处理一些耗时短的操作。耗时长的最好还用线程池。

(2)当activity销毁的时候在onDestroy()方法中调用AsyncTask的cancel方法 否则会造成内存泄露或者崩溃

(3)AsyncTask串行的时候稳定 并行的时候不稳定。

HandlerThread

多次创建和销毁线程是很消耗内存资源的。

本质:是一个线程类,继承了Thread,HandlerThread有自己的Looper对象可以进行looper循环。所以其内部可以创建handler来发送和处理消息。

优点:不会阻塞。减少了对性能的消耗。

缺点:不能同时进行多任务处理,需要等待。效率低

使用场景源码分析

View的绘制流程

measure——>layout——drow

measure 自上而下递归测量

MeasureSpac 测量规格是一个32为的int只。前面的两位表示测量模式,后面的30位表示在此模式下的大小

EXACTLY

父容器已经测量出View所需要的精确大小,这个时候View的最终大小就是SpecSize所指定的值。它对应于LayoutParams中的match_parent和具体的数值这两种模式。

AT_MOST

父容器指定了一个可用大小即SpecSize,View大小不能大于这个值,具体是什么值要看不同View的具体实现。它对应于LayoutParams中的Wrap_content

UNSPECIFIED

父容器不对View有任何限制,要多大给多大,这种情况一般用于系统内部,表示一种测量的状态。

layout 自上而下递归布局

该方法在ViewGroup中定义是抽象函数,继承该类必须实现onLayout方法,而ViewGroup的onMeasure并非必须重写的。View的放置都是根据一个矩形空间放置的,onLayout传下来的l,t,r,b分别是放置父控件的矩形可用空间(除去margin和padding的空间)的左上角的left、top以及右下角right、bottom值。

drow

invalidate() 重新绘制

requestLayout() 重新布局

事件分发的机制

PhoneWindow 所有view的最顶层

DectorView Window界面的最顶层View

dispatchTouchEvent():

决定事件是自己处理还是给子view处理 通过调用onInterceptTouchEvent()来拦截事件

onInterceptTouchEvent():

用来拦截事件

onTouchEvent(MotionEvent event):

处理事件

listview相关

(1)适配器模式

保证数据和view的分离

(2)缓存机制

recycleBin机制,总共创建屏幕可见的子view条数,将滑出屏幕的view缓存起来从底部复用。

(3)优化

convertView 缓存优化。

ViewHolder 减少findViewById()的次数

getView() 方法中少做耗时操作。

安卓构建

安卓的构建流程:

把.java文件变异成.class文件,然后把.class和依赖的.jar文件打包成安卓可识别的.dex文件。然后打包资源文件,将他们合并成未签名的包,最后签名形成完成的包。

自动化构建 jenkins

git 版本管理

proguard混淆

开源框架

okhttp

retrofit 动态代理

(1)通过method转换成ServiceMethod对象。

(2)通过ServiceMethod获取okHttpCall

(3)把okHttpCall封装返回call对象

butterknife

glide
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android