美文网首页
基础知识(三)android

基础知识(三)android

作者: 胖胖O蓝胖子 | 来源:发表于2018-10-07 17:06 被阅读0次

    ContentProvider:学习笔记| AS入门(八) 组件篇之ContentProvider - 简书

    ContentProvider有存储数据的功能,ContentProvider有两种形式:可以使用现有的内容提供者来读取和操作相应程序中的数据,也可以创建自己的内容提供者给这个程序的数据提供外部访问接口。

    从系统提供的Provider访问数据

    既然ContentProvider有对外共享数据的功能,换句话说,其他应用程序可以通过ContentProvider对应用中的数据进行增删改查(例如访问通讯录),访问ContentProvider中共享的数据的方法是:

    第一步:通过Context 中的getContentResolver()方法实例化一个ContentResolve对象。

    第二步:调用该对象的增删改查方法去操作ContentProvider中的数据。

    具体内容查看上述链接。

    Android跨进程通信:

    1.Bundle/Intent传递数据

    2.文件共享

    3.Messenger

    4.AIDL

    5.ContentProvider

    Bundle 机制:Bundle实现了Parcelable接口,所以他可以方便的在不同进程间传输。

    场景:

    Activity状态数据的保存与恢复涉及到的两个回调:void onSaveInstanceState (Bundle outState)、void onCreate (Bundle savedInstanceState)

    Fragment的setArguments方法:void setArguments (Bundle args)

    消息机制中的Message的setData方法:void setData (Bundle data)

    Bundle其实就是一个容器,内部使用了Arraymap去存储数据,那么就必然会提供get,put方法

    AIDL :Android 进阶7:进程通信之 AIDL 的使用 - 张拭心的博客 shixinzhang - CSDN博客

    AIDL(Android 接口定义语言) 是 Android 提供的一种进程间通信 (IPC) 机制。

    我们可以利用它定义客户端与服务使用进程间通信 (IPC) 进行相互通信时都认可的编程接口。

    在 Android 上,一个进程通常无法访问另一个进程的内存, Android 会使用 AIDL 来处理。

    通过这种机制,我们只需要写好 aidl 接口文件,编译时系统会帮我们生成 Binder 接口。

    AIDL 支持的数据类型共 4 种:

    1.Java 的基本数据类型

    2.List 和 Map 

        元素必须是 AIDL 支持的数据类型

        Server 端具体的类里则必须是 ArrayList 或者 HashMap

    3.其他 AIDL 生成的接口

    4.实现 Parcelable 的实体

    AIDL 的编写主要为以下三部分:

    1.创建 AIDL

        创建要操作的实体类,实现Parcelable接口,以便序列化/反序列化

        新建 aidl 文件夹,在其中创建接口 aidl 文件以及实体类的映射 aidl 文件

        Make project ,生成 Binder 的 Java 文件

    2.服务端

        创建 Service,在其中创建上面生成的 Binder 对象实例,实现接口定义的方法

        在onBind()中返回

    3.客户端

        实现ServiceConnection接口,在其中拿到 AIDL 类

        bindService()

    我们从Android对aidl文件自动生成的java类中可以看到asInterface()这个接口的实现,大概的意思就是: 

    如果客户端和服务端在同一个进程下,那么asInterface()将返回Stub对象本身,否则返回Stub.Proxy对象。

    Binder机制:Android系统中,涉及到多进程间的通信底层都是依赖于Binder IPC机制。

    性能方面

    在移动设备上(性能受限制的设备,比如要省电),广泛地使用跨进程通信对通信机制的性能有严格的要求,Binder相对出传统的Socket方式,更加高效。Binder数据拷贝只需要一次,而管道、消息队列、Socket都需要2次,共享内存方式一次内存拷贝都不需要,但实现方式又比较复杂。

    Binder原理

    Binder通信采用C/S架构,从组件视角来说,包含Client、Server、ServiceManager以及binder驱动,其中ServiceManager用于管理系统中的各种服务。

    Binder运行机制:

    注册服务(addService):Server进程要先注册Service到ServiceManager。该过程:Server是客户端,ServiceManager是服务端。

    获取服务(getService):Client进程使用某个Service前,须先向ServiceManager中获取相应的Service。该过程:Client是客户端,ServiceManager是服务端。

    使用服务:Client根据得到的Service信息建立与Service所在的Server进程通信的通路,然后就可以直接与Service交互。该过程:client是客户端,server是服务端。


    序列化:Serializable接口和Parcelable接口

    含义:序列化表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。

    场景:需要通过Intent和Binder等传输类对象就必须完成对象的序列化过程。

    Serializable:java提供的接口,将java对象转为字节序列,需要继承接口,为基于磁盘或者网络的对象序列化,调用WriteObject(obj)方法实现。

    Parcelable:android提供的接口,基于内存的对象序列化,将对象拆分为可传递的数据类型,基于内存的速度要快于基于磁盘的接口。

    serialVersionUID

    含义:是Serializable接口中用来辅助序列化和反序列化过程。

    注意:原则上序列化后的数据中的serialVersionUID要和当前类的serialVersionUID 相同才能正常的序列化

    简单描述Handler:

    andriod提供了Handler 和 Looper 来满足线程间的通信。Handler先进先出原则。Looper类用来管理特定线程内对象之间的消息交换

    Message(消息):需要被传递的消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,最终由Handler处理。

    MessageQueue(消息队列):用来存放Handler发送过来的消息,内部通过单链表的数据结构来维护消息列表,等待Looper的抽取。

    Handler(处理者):负责Message的发送及处理。

    Handler.sendMessage():向消息池发送各种消息事件。

    Handler.handleMessage() :处理相应的消息事件。

    Looper(消息泵):通过Looper.loop()不断地从MessageQueue中抽取Message,按分发机制将消息分发给目标处理者。

    存在关系:

    一个Thread只能有一个Looper,可以有多个Handler;

    Looper有一个MessageQueue,可以处理来自多个Handler的Message;

    MessageQueue有一组待处理的Message,这些Message可来自不同的Handler;

    Message中记录了负责发送和处理消息的Handler;

    Handler中有Looper和MessageQueue;

    UI的线程looper不会卡死(ANR)的原因:

    ActivityThread的main方法主要就是做消息循环,一旦退出消息循环,那么你的应用也就退出了。looper采用,epoll+pipe,有消息就依次执行,没消息就block住,让出CPU,等有消息了,epoll会往pipe中写一个字符,把主线程从block状态唤起,主线程就继续依次执行消息。

    Android的线程和线程池:

    AsyncTask

    HandlerThread

    IntentService(见前文)

    按用途可分为两类:

    主线程:一般一个进程只有一个主线程,主要处理界面交互相关的逻辑。

    子线程:除主线程之外都是子线程,主要用于执行耗时操作

    按形态可分为三类:

    AsyncTask:底层封装了线程池和Handler,便于执行后台任务以及在子线程中进行UI操作。

    HandlerThread:一种具有消息循环的线程,其内部可使用Handler。

    IntentService:是一种异步、会自动停止的服务,内部采用HandlerThread。


    1.AsyncTask                                                                                                          Android AsyncTask完全解析,带你从源码的角度彻底理解 - 郭霖的专栏 - CSDN博客

    AsyncTask:一种轻量级的异步任务类。AsyncTask的好处:创建异步任务更简单,直接继承它可方便实现后台异步任务的执行和进度的回调更新UI,而无需编写任务线程和Handler实例就能完成相同的任务。

    1.execute(Params... params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。

    2.onPreExecute(),在execute(Params... params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。

    3.doInBackground(Params... params),在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。

    4.onProgressUpdate(Progress... values),在调用publishProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件上。

    5.onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。

    工作原理:

    内部有一个静态的Handler对象即InternalHandler

    作用:将执行环境从线程池切换到主线程;通过它来发送任务执行的进度以及执行结束等消息。

    注意:必须在主线程中创建

    内部有两个线程池:

    SerialExecutor:用于任务的排队,默认是串行的线程池

    THREAD_POOL_EXECUTOR:用于真正执行任务。

    排队执行过程:把参数Params封装为FutureTask对象,相当于Runnable;调用SerialExecutor.execute()将FutureTask插入到任务队列tasks;若没有正在活动的AsyncTask任务,则就会执行下一个AsyncTask任务。执行完毕后会继续执行其他任务直到所有任务都完成。即默认使用串行方式执行任务。

    2.HandlerThread

    HandlerThread是一个线程类,它继承自Thread,与普通Thread的区别:具有消息循环的效果。内部HandlerThread.run()方法中有Looper,通过Looper.prepare()来创建消息队列,并通过Looper.loop()来开启消息循环。

    实现方法步骤:实例化一个HandlerThread对象,参数是该线程的名称;通过HandlerThread.start()开启线程;实例化一个Handler并传入HandlerThread中的looper对象,使得与HandlerThread绑定;利用Handler即可执行异步任务;当不需要HandlerThread时,通过HandlerThread.quit()/quitSafely()方法来终止线程的执行。

    Animation(android动画):要点提炼|开发艺术之Animation - 简书

    1.View动画(View Animation)/补间动画(Tween animation)

    2.逐帧动画(Drawable Animation)

    3.属性动画(Property Animation)

    View动画:平移动画、缩放动画、旋转动画和透明度动画

    通过xml定义:该xml文件创建在res/anim/ 下。

    根节点<set>,子节点<translate>、<scale>、<rotate>、<alpha >,分别对应四种View动画:

    通过Java代码动态创建具体步骤:

    step1:创建TranslateAnimation、RotateAnimation、ScaleAnimation或AlphaAnimation对象。

    step2:设置创建的动画对象的属性,如动画执行时间、延迟时间、起始位置、结束位置等。

    step3:通过View.startAnimation()方法开启动画。

    step4:可通过Animation.setAnimationListener()设置动画的监听器。

    Activity的切换效果:

    该xml文件创建在res/anim/ 下,Activity默认是有切换效果的,若需要自定义切换效果,需要用到overridePendingTransition(int inAnim, int outAnim)方法。

    startActivity(intent); 

    overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);

    逐帧动画对应类AnimationDrawable:

    a.通过xml定义:

    该xml文件创建在res/drawable/ 下。根节点<animation-list>,属性android:oneshot表示是否执行一次;子节点<item> 下可设置轮播的图片资源id和持续时间。在xml声明好之后,将它作为View的背景并通过AnimationDrawable来播放即可。

    b.通过Java代码动态创建:

    AnimationDrawable ad =newAnimationDrawable();

    for(inti =0; i <4; i++) {

    Drawable drawable = getResources().getDrawable(getResources().getIdentifier("xxx"+ i,"drawable", getPackageName())); 

     ad.addFrame(drawable,500);  } 

     ad.setOneShot(false);

    mView.setBackgroundResource(ad);

    ad.start();

    属性动画:通过改变对象属性来实现动画,真正改变了view,Android 属性动画:这是一篇很详细的 属性动画 总结&攻略 - 简书

    插值器、估值器:Android 动画:你真的会使用插值器与估值器吗?(含详细实例教学) - 简书

    实现方式:在res/animator/下可创建属性动画的xml文件。其中,根节点<set>对应AnimatorSet类,子节点<objectAnimator>对应ObjectAnimator类、<animator>对应ValueAnimator类。

    ObjectAnimator与 ValueAnimator类的区别:

    ValueAnimator 类是先改变值,然后手动赋值给对象的属性从而实现动画;是间接对对象属性进行操作;

    ObjectAnimator 类是先改变值,然后自动赋值给对象的属性从而实现动画;是直接对对象属性进行操作;

    Android系统的有哪些安全机制:

    应用程序签名机制,权限申明机制,访问控制机制,进程通讯机制,内存管理机制。

    未完待续..............

    相关文章

      网友评论

          本文标题:基础知识(三)android

          本文链接:https://www.haomeiwen.com/subject/qdilaftx.html