Android 语音TTS 辨认全链途经程
- 本地灌音 =》 ASR辨认 =》哀求配景语义 =》语义落域分发返回 =》 本地仲裁处理处罚落域分发 =》 TTS播报
- 下面是语音链路的一些根本思绪
- 灌音 :Android根本灌音为48K的采样率 语音这边须要做降采样处理处罚 降采样为16K。通过Android原生灌音将音频给到引擎
- 唤醒:一样平常唤醒都是做本地唤醒,全部wakeup唤醒引擎。也可以通过唤醒引擎做一些免唤醒功能
- 语音辨认,辨认分为两种:
3.1 离线辨认,走本地辨认引擎,
长处:辨认快
缺点:须要精准辨认,并不能做太多泛化处理处罚。对音频要求比力高
3.2 在线辨认,走云端辨认引擎
长处 :可以含糊匹配,多泛化
缺点 :网路查的环境下辨认很慢
- 云端与离线云端技能分发
- TTS播报:由云端或本地汲取文本举行语音音频合成。举行播报
Android 屏幕适配相关,方案
- 通过dp加上自顺应布局可以根本解决屏幕碎片化的题目。也是Android保举利用的屏幕兼容性适配方案。
- 根据ui计划图的宽度dp值,算出当前屏幕每dp占当前屏幕多少像素值(也就是density)。
- 根据ui计划图的宽度dp值,算出当前屏幕分成ui计划图的宽高度dp份后,每dp占当前屏幕现实多少dp,然后这个现实dp值再根dpi转换成详细的像素值。
- 自界说像素适配,以美工的计划尺寸为原始尺寸,根据差异装备的密度 计算出宽和高 参考UIAdapter。假如想体现屏幕的1/3的话就是360了宽度,是根据计划师给出来的宽度举行设置
- 百分比适配。这是Google 提出来的一个解决适配方案,想要利用必须添加依赖
implementation 'com.android.support:percent:28.0.0'主要就是两个类
PercentRelativeLayout PercentFrameLayout
多线程,线程池 相关
- 1.继承Thread重写run方法
- 2.实现Runnable重写run方法
- 3.实现Callable重写call方法
1.3 实现Callable重写call方法
实现Callable和实现Runnable类似,但是功能更强大
可以在任务竣事后提供一个返回值,Runnable不可
call方法可以抛出非常,Runnable的run方法不可
可以通过运行Callable得到的Fulture对象监听目标线程调用call方法的效果,得到返回值,(fulture.get(),调用后会壅闭,直到获取到返回值)
- Android中最常见的四类具有差异特性的线程池分别为FixThreadPool、CachedThreadPool、ScheduleThreadPool和SingleThreadExecutor
public static ExecutorService newFixThreadPool(int nThreads){ return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());}//利用Executors.newFixThreadPool(5).execute(r);
- 从设置参数来看,FixThreadPool只有核心线程,而且数目固定的,也不会被接纳,全部线程都运动时,因为队列没有限定巨细,新任务会等候实验。
- FixThreadPool着实就像一堆人列队上公厕一样,可以无数多人列队,但是厕所位置就那么多,而且没人上时,厕所也不会被拆迁
- 由于线程不会接纳,FixThreadPool会更快地相应外界哀求,这也很容易明确,就似乎有人忽然想上厕所,公厕不是现用现建的
- SingleThreadPool(公厕里只有一个坑位)
public static ExecutorService newSingleThreadPool (int nThreads){ return new FinalizableDelegatedExecutorService ( new ThreadPoolExecutor (1, 1, 0, TimeUnit. MILLISECONDS, new LinkedBlockingQueue<Runnable>()) );}//利用Executors.newSingleThreadPool ().execute(r);
- 从设置参数可以看出,SingleThreadPool只有一个核心线程,确保全部任务都在同一线程中按次序完成。因此不须要处理处罚线程同步的题目。
- 可以把SingleThreadPool简单的明确为FixThreadPool的参数被手动设置为1的环境,即Executors.newFixThreadPool(1).execute(r)。以是SingleThreadPool可以明确为公厕里只有一个坑位,先来先上。为什么只有一个坑位呢,因为这个公厕是收费的,收费的大爷上年岁了,只能管理一个坑位,多了就管不外来了(线程同步题目)
- CachedThreadPool(一堆人去一家很大的咖啡馆喝咖啡)
public static ExecutorService newCachedThreadPool(int nThreads){ return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit. SECONDS, new SynchronousQueue<Runnable>());}//利用Executors.newCachedThreadPool().execute(r);
- CachedThreadPool只有非核心线程,最大线程数非常大,全部线程都运动时,会为新任务创建新线程,否则利用空闲线程(60s空闲时间,过了就会被接纳,以是线程池中有0个线程的大概)处理处罚任务。
- 任务队列SynchronousQueue相称于一个空聚集,导致任何任务都会被立即实验。
- CachedThreadPool就像是一堆人去一个很大的咖啡馆喝咖啡,里面服务员大概多,随时去,随时都可以喝到咖啡。但是为了相应国家的“光盘举措”,一个人喝剩下的咖啡会被生存60秒,供新来的客人利用,哈哈哈哈哈,好恶心啊。假如你运气好,没有剩下的咖啡,你会得到一杯新咖啡。但是从前客人剩下的咖啡高出60秒,就变质了,会被服务员接纳掉。
- 比力得当实验大量的耗时较少的任务。喝咖啡人挺多的,喝的时间也不长
- ScheduledThreadPool(4个里面唯逐一个有延迟实验和周期重复实验的线程池)
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize){return new ScheduledThreadPoolExecutor(corePoolSize);}public ScheduledThreadPoolExecutor(int corePoolSize){super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedQueue ());}//利用,延迟1秒实验,每隔2秒实验一次Runnable rExecutors. newScheduledThreadPool (5).scheduleAtFixedRate(r, 1000, 2000, TimeUnit.MILLISECONDS);
- 核心线程数固定,非核心线程(闲着没活干会被立即接纳)数没有限定。
- 从上面代码也可以看出,ScheduledThreadPool主要用于实验定时任务以及有固定周期的重复任务。
Handler 先容
- 由于Android中主线程是不能举行耗时操纵的,子线程是不能举行更新UI的。以是就有了handler,它的作用就是实现线程之间的通讯。 handler整个流程中,主要有四个对象,handler,Message,MessageQueue, Looper。当应用创建的时间,就会在主线程中创建handler对象, 我们通过要传送的消息生存到Message中,handler.post handler通过调用sendMessage方法将Message发送到MessageQueue中,Looper对象就会不断的调用loop()方法 不断的从MessageQueue中取出Message交给handler举行处理处罚。从而实现线程之间的通讯
说下 handler 原理
- Handler,Message,looper 和 MessageQueue 构成了安卓的消息机制,handler创建后可以通过 sendMessage 将消息加入消息队列,然后 looper不断的将消息从 MessageQueue 中取出来,回调到 Hander 的 handleMessage方法,从而实现线程的通讯。
- 在UI线程创建Handler,此时我们不须要手动开启looper,因为在应用启动时,在ActivityThread的main方法中就创建了一个当前主线程的looper,并开启了消息队列,消息队列是一个无限循环,为什么无限循环不会ANR ? 因为应用的整个生命周期就是运行在这个消息循环中的,安卓是由变乱驱动的,Looper.loop不断的汲取处理处罚变乱,每一个点击触摸大概Activity每一个生命周期都是在Looper.loop的控制之下的,looper.loop一旦竣事,应用步伐的生命周期也就竣事了。我们可以想想什么环境下会发生ANR,第一,变乱没有得到处理处罚
- 变乱正在处理处罚,但是没有及时完成,而对变乱举行处理处罚的就是looper,以是只能说变乱的处理处罚假如壅闭会导致ANR,而不能说looper的无限循环会ANR。
另一种环境就是在子线程创建Handler,此时由于这个线程中没有默认开启的消息队列,以是我们须要手动调用looper.prepare(),并通过looper.loop开启消息
- 主线程Looper从消息队列读取消息,当读完全部消息时,主线程壅闭。子线程往消息队列发送消息,而且往管道文件写数据,主线程即被唤醒,从管道文件读取数据,主线程被唤醒只是为了读取消息,当消息读取完毕,再次就寝。因此loop的循环并不会对CPU性能有过多的消耗
Activity A跳转Activity B,再按返回键,生命周期实验的次序?
- A.onPause() B.onCreate() B.onStart() B.onResume() A.onStop()
- 别的 假如Activity B是透明的 大概Activity B 并未完全遮住Activity A,那么上述操纵点击Activity A 跳转 Activity B 生命周期中A.onStop()是不会被调用的,因为Activity A还可见,以是Activity A不能被制止
View 的绘制流程
- Activity、Window、DecorView之间关系
public void setContentView(@LayoutRes int layoutResID) { // 将xml布局通报到Window当中 getWindow().setContentView(layoutResID); initWindowDecorActionBar(); }
- 从代码可以看出,Activity的setContentView实质是将View通报到Window的setContentView()方法中,Window的setContenView会在内部调用installDecor()方法创建DecorView
- View的绘制是从ViewRootImpl的performTraversals()方法开始,从最顶层的View(ViewGroup)开始逐层对每个View举行绘制操纵
- measure:为丈量宽高过程,假如是ViewGroup还要在onMeasure中对全部子View举行measure操纵。
- layout:用于摆放View在ViewGroup中的位置,假如是ViewGroup要在onLayout方法中对全部子View举行layout操纵。
- draw:往View上绘制图像。
- View 的绘制流程是 measure -> layout -> draw
View 变乱分发机制
- dispatchTouchEvent ,这个方法主要是用来分发变乱的
- onInterceptTouchEvent,这个方法主要是用来拦截变乱的(须要注意的是 ViewGroup 才有这个方法,View 没有 onInterceptTouchEvent 这个方法)
- onTouchEvent 这个方法主要是用来处理处罚变乱的
- requestDisallowInterceptTouchEvent(true),这个方法可以或许影响父View是否拦截变乱,true 体现父 View 不拦截变乱,false 体现父 View 拦截变乱
- 当触摸变乱发生时,起首 Activity 将 TouchEvent 通报给最顶层的 View,TouchEvent开始到达最顶层 view 的 dispatchTouchEvent,然后由 dispatchTouchEvent方法举行分发,
假如dispatchTouchEvent返回true 消耗变乱,变乱闭幕。
假如dispatchTouchEvent返回 false ,则回传给父View的onTouchEvent变乱处理处罚;
假如dispatchTouchEvent返回super的话,默认会调用本身的onInterceptTouchEvent方法。
默认的环境下onInterceptTouchEvent回调用super方法,super方法默认返回false,以是会交给子View的onDispatchTouchEvent方法处理处罚
假如 interceptTouchEvent 返回 true ,也就是拦截掉了,则交给它的 onTouchEvent 来处理处罚,
假如 interceptTouchEvent 返回 false ,那么就通报给子 view ,由子 view 的 dispatchTouchEvent 再来开始这个变乱的分发。
Activity 四种启动模式
- standard : 默认启动模式,每开启一个activity就在任务栈中创建一个新的实例.Top single 顶部只有一个 不答应存在两个相同的Activity.利用场景:根本绝大多数地方都可以用。
- singleTop: 假如在任务的栈顶恰好存有该 Activity的实例,则会通过调用 onNewIntent() 方法举行重用,否则就会同 standard 模式一样,创建新的实例并放入栈顶。即便栈中已经存在了该 Activity 的实例,也会创建新的实例
当且仅当启动的 Activity 和上一个 Activity 同等的时间才会通过调用 onNewIntent()方法重用 Activity 。利用场景:资讯阅读类 APP 的内容界面。
- singleTask : 在同一个任务栈中,假如要启动的目标Activity已经在栈中,则会复用该Activity,并调用其onNewIntent()方法,而且该Activity上面的Activity会被扫除,假如栈中没有,则创建新的实例。利用场景:浏览器的主页面,大概大部门 APP 的主页面。
- singleInstance: 指定为singleInstance模式的运动会启用一个新的返回栈来管理这个运动。在一个新栈中创建该 Activity 的实例,并让多个应用共享该栈中的该 Activity 实例。一旦该模式的 Activity 实例已经存在于某个栈中,任何应用再激该死 Activity 时都会重用该栈中的实例,是的,依然是调用 onNewIntent()方法。其效果相称于多个应用共享一个应用,不管是谁激活,该 Activity 都会进入同一个应用中。但值得引起注意的是:singleInstance 不要用于中央页面,假如用户中央页面,跳转会出现很难熬的题目。 这个在现实开辟中我暂未遇到过, Android 体系的来电页面,多次来电都是利用的同一个 Activity。
Service启动方式
- startService. startService() 启动一个 Service。一旦启动,Service 将不绝运行在配景,纵然启动这个 Service 的组件已经被烧毁。通常一个被 start 的 Service 会在配景实验单独的操纵,也并不须要给启动它的组件返回效果。只有当 Service 本身调用 stopSelf() 大概别的组件调用 stopService() 才会制止。
- **bindService **. bindService() 来绑定一个 Service。这种方式会让 Service 和启动它的组件绑定在一起,当启动它的组件烧毁的时间,Service 也会主动举行 unBind 操纵。同一个 Service 可以被多个组件绑定,只有全部绑定它的组件都举行了 unBind 操纵,这个 Service 才会被烧毁
- Service 的生命周期
- 当调用 startService() 去 start 一个 Service 后,仍旧可以 bind 这个 Service。好比:当播放音乐的时间,须要调用 startService() 启动指定的音乐,当须要获取该音乐的播放进度的时间,又须要调用 bindService(),在这种环境下,除非 Service 被 unbind,此前调用 stopService() 和 stopSelf() 都不能制止该 Service
- 完备生命周期(entire lifetime):从 onCreate() 被调用,到 onDestroy() 返回。和 Activity 类似,一样平常在 onCreate() 方法中做一些初始化的工作,在 onDestroy() 中做一些资源开释的工作。如,若 Service 在配景播放一个音乐,就须要在 onCreate() 方法中开启一个线程启动音乐,并在 onDestroy() 中竣事线程。
- 运动生命周期(activity lifetime):从 onStartCommand() 或 onBind() 回调开始,由相应的 startService() 或 bindService() 调用。start 方式的运动生命周期竣事就意味着完备证实周期的竣事,而 bind 方式,当 onUnbind() 返回后,Service 的运动生命周期竣事。
- 是 startService() 照旧 bindService() 启动 Service,onCreate() 和 onDestroy() 均会被回调
Service 的 onCreate() 可以实验耗时操纵吗?
- Service 运行在主线程中,它并不是一个新的线程,也不是新的历程,以是并不能实验耗时操纵。
假如要在 Service 中实验耗时操纵,怎么做?
- 利用 AysncTask 或 HandlerThread 来更换 Thread 创建线程。
- IntentService 继承于 Service,若 Service 不须要同时处理处罚多个哀求,那么利用 IntentService 将是最好选择。只须要重写 onHandleIntent() 方法,该方法汲取一个回调的 Intent 参数, 在方法内举行耗时操纵,因为它默认开启了一个子线程,操纵实验完成后也无需手动调用 stopSelf() 方法,onHandleIntent() 将会主动调用该方法
Service 与 IntentService区别
- Service 不是运行在独立的线程,以是不发起在Service中编写耗时的逻辑和操纵,否则会引起ANR。
- IntentService
- 可用于实验配景耗时的任务,任务实验后会主动制止。
- 具有高优先级,得当高优先级的配景任务,且不容易被体系杀死。
- 可以多次启动,每个耗时操纵都会以工作队列的方式在IntentService的onHandleIntent回调方法中实验
Serializable 和Parcelable的区别
- 平台区别。Serializable是属于 Java 自带的,体现一个对象可以转换成可存储大概可传输的状态,序列化后的对象可以在网络上举行传输,也可以存储到本地。
Parcelable 是属于 Android 专用。不外差异于Serializable,Parcelable实现的原理是将一个完备的对象举行分解。而分解后的每一部门都是Intent所支持的数据范例。
- 编写上的区别。Serializable代码量少,写起来方便
Parcelable代码多一些,略复杂
- 选择的原则
- 假如是仅仅在内存中利用,好比activity、service之间举行对象的通报,猛烈保举利用Parcelable,因为Parcelable比Serializable性能高很多。因为Serializable在序列化的时间会产生大量的暂时变量, 从而引起频仍的GC。
- 假如是长期化操纵,保举Serializable,固然Serializable效率比力低,但是照旧要选择它,因为在外界有厘革的环境下,Parcelable不能很好的生存数据的连续性。
- Serializable的本质是利用了反射,序列化的过程比力慢,这种机制在序列化的时间会创建很多暂时的对象,比引起频仍的GC、
- Parcelable方式的本质是将一个完备的对象举行分解,而分解后的每一部门都是Intent所支持的范例,如许就实现了通报对象的功能了
Serializable中为什么要设置UID,设置UID与不设置UID值的区别和影响 ?
- serialVersionUID 是用来辅助序列化和反序列化的过程。 序列化后的数据中的serialVersionUID只有和当前类的serialVersionUID同等才气成功的反序列化
- serialVersionUID 实用于java序列化机制。简单来说,JAVA序列化的机制是通过判断类的serialVersionUID来验证的版本同等的。在举行反序列化时,JVM会把传来的字节流中的serialVersionUID于本地相应实体类的serialVersionUID举行比力。假如相同分析是同等的,可以举行反序列化,否则会出现反序列化版本同等的非常,便是InvalidCastException。
- 详细序列化的过程 :序列化操纵时会把体系当前类的serialVersionUID写入到序列化文件中,当反序列化时体系会主动检测文件中的serialVersionUID,判断它是否与当前类中的serialVersionUID同等。假如同等分析序列化文件的版本与当前类的版本是一样的,可以反序列化成功,否则就失败;
- serialVersionUID有两种体现的天生方式:
- 默认的1L,好比:private static final long serialVersionUID = 1L;
- 根据包名,类名,继承关系,非私有的方法和属性,以及参数,返回值等诸多因子计算得出的,非常复杂天生的一个64位的哈希字段。根本上计算出来的这个值是唯一的。好比:private static final long serialVersionUID = xxxxL;
注意:体现声明serialVersionUID可以制止对象不同等
内存走漏的场景息争决办法
- 非静态内部类的静态实例
非静态内部类会持有外部类的引用,假如非静态内部类的实例是静态的,就会长期的维持着外部类的引用,构造被体系接纳,解决办法是利用静态内部类
- 多线程相关的匿名内部类和非静态内部类
匿名内部类同样会持有外部类的引用,假如在线程中实验耗时操纵就有大概发生内存走漏,导致外部类无法被接纳,直到耗时任务竣事,解决办法是在页面退出时竣事线程中的任务
- Handler内存走漏
Handler导致的内存走漏也可以被归纳为非静态内部类导致的,Handler内部message是被存储在MessageQueue中的,有些message不能立即被处理处罚,存在的时间会很长,导致handler无法被接纳,假如handler黑白静态的,就会导致它的外部类无法被接纳,解决办法是1.利用静态handler,外部类引用利用弱引用处理处罚2.在退出页面时移除消息队列中的消息
- Context导致内存走漏
根据场景确定利用Activity的Context照旧Application的Context,因为二者生命周期差异,对于不必须利用Activity的Context的场景(Dialog),同等接纳Application的Context,单例模式是最常见的发生此走漏的场景,好比传入一个Activity的Context被静态类引用,导致无法接纳
- 静态View导致走漏
利用静态View可以制止每次启动Activity都去读取并渲染View,但是静态View会持有Activity的引用,导致无法接纳,解决办法是在Activity烧毁的时间将静态View设置为null(View一旦被加载到界面中将会持有一个Context对象的引用,在这个例子中,这个context对象是我们的Activity,声明一个静态变量引用这个View,也就引用了activity)
- WebView导致的内存走漏
WebView只要利用一次,内存就不会被开释,以是WebView都存在内存走漏的题目,通常的解决办法是为WebView单开一个历程,利用AIDL举行通讯,根据业务需求在符合的时机开释掉
- 资源对象未关闭导致
如Cursor,File等,内部每每都利用了缓冲,会造成内存走漏,肯定要确保关闭它并将引用置为null
- 集会合的对象未清算
集实用于生存对象,假如聚集越来越大,不举行公道的清算,尤其是入股聚集是静态的
- Bitmap导致内存走漏
bitmap是比力占内存的,以是肯定要在不利用的时间及时举行清算,制止静态变量持有大的bitmap对象
- 监听器未关闭
很多须要register和unregister的体系服务要在符合的时间举行unregister,手动添加的listener也须要及时移除
EventBus原理
- 主要是维护了几个数组,然后根据对应的key找到对应的注册对象,通过放射的方式调用对应的方法。
- EventBus 2.x 是接纳反射的方式对整个注册的类的全部方法举行扫描来完成注册,固然会有性能上的影响。EventBus 3.0 中EventBus提供了EventBusAnnotationProcessor注解处理处罚器来在编译期通过读取@Subscribe()注解并剖析、处理处罚此中所包含的信息,然后天生java类来生存全部订阅者关于订阅的信息,如许就比在运行时利用反射来得到这些订阅者的信息速率要快
/注册变乱EventBus.getDefault().register(this);//注册方法@Subscribepublic void event(BaseEventBusBeaan message) { LogUtils.d("EventBusActivity event");} //发送变乱EventBus.getDefault().post(new BaseEventBusBeaan("123", new Bundle())); //反注册EventBus.getDefault().unregister(this);总结一下大概的流程
- 通过apt在编译期将全部被 @Subscribe注解的函数添加到MyEventBusIndex对象中。
- 在register过程中天生subscriptionsByEventType的数据。
- 在 post过程中通过subscriptionsByEventType数据查找对应的函数,然后再通过反射的方式调用。
优先级的题目
这个题目也非常简单,只须要在插入数据的时间,做下优先级判断即可。
Android 热更新 流程和原理
- 一个完备的项目应该有如下分支:
develop分支---- 这个分支中放的是线上的发布版本。
bugfix分支---- 这个是热更新分支,由develop中迁出。
master分支---- 这个是开辟中的分支
- 热更新应当按照如下步调举行:
- 线上检测到严肃的crash
- 从develop中拉出一个线上的最新版,在bugfix分支上举行题目标修复
- jenkins构建和补丁的天生
- app通过推送或主动拉取补丁文件
- 将bugfix代码合到master上,包管以后不会出现该题目
- Dexposed :该框架是阿里巴巴开源的一个Android平台下的无侵入的运行时AOP(面向方向编程)框架。基于从前开源的一个Xposed框架实现的。Dexposed框架基于Hook技术实现功能,不但可以hook你本身的步伐代码,也可以hook你的应用步伐中调用的Android框架中的函数。基于动态类加载技术,运行中的app可以加载一小段颠末编译的Java的代码,而且在不须要重写APP的条件下,就可以实现修改APP
- AndFix:该框架同样出自阿里。与Dexposed不是同一个团队。AndFix也是基于Xposed头脑。而相比第一个,它是一个更纯粹的热修复的框架。
- Nuwa:它着实是基于类加载器ClassLoader加载Dex文件。假如多个Dex文件存在相同的类,那么排在前面的Dex文件就将优先被选择。这是热更新最主要的头脑,它通过不断地去轮询,去遍历Dex的一个数组,然后把我们须要修改的类的dex文件加到最前面,如许当轮询遍历时就不会加载有题目标谁人类。
- Android的类加载机制 :Android的类加载器主要有如许两个:PathClassLoader和DexClassLoader。PathClassLoader主要用于加载体系的类和应用类,DexClassLoader主要加载Dex文件,Jar文件,apk文件等。
- 热修复机制:在BaseClassLoader中会创建一个dexElements数组,然后我们会通过ClassLoader遍历这个数组,加载这个数组中的dex文件。如许当BaseClassLoader加载到准确的类以后,就不会去加载有Crash的谁人类。因此我们就将这个有题目修复后的类放入Dex文件当中,让这个Dex文件排在dexElements前面。如许BaseClassLoader就不会加载到处于反面的谁人Dex文件。如许就完成了整个热修复过程。
Android线程间通讯四种方式:
- 通过Handler机制
主线程中界说Handler,子线程发消息,关照Handler完成UI更新,Handler对象必须界说在主线程中,假如是多个类直接相互调用,就不是很方便,须要通报content对象或通过接口调用。别的Handler机制与Activity生命周期不同等的缘故因由,容易导致内存走漏,不保举利用。
- runOnUiThread方法,用Activity对象的runOnUiThread方法更新,在子线程中通过runOnUiThread()方法更新UI,猛烈保举利用。
- 3.View.post(Runnable r)这种方法更简单,但须要通报要更新的View已往,保举利用
- AsyncTask,即异步任务,是Android给我们提供的一个处理处罚异步任务的类.通过此类,可以实现UI线程和配景线程举行通讯,配景线程实验异步任务,并把效果返回给UI线程
Android中有哪些历程间通讯方式?
- Binder 简单易用 只能传输Bundle支持的数据范例 四大组件间的历程间通讯
文件共享 简单易用 不实用高并发场景,而且无法做到历程间即时通讯 实用于无关发的环境下,交换简单的数据,对及时性要求不高的场景。
- AIDL功能强大,支持一对多及时并发通讯 利用稍复杂,须要处理处罚好线程间的关系 一对多通讯且有RPC需求
- Messenger功能一样平常,支持一对多串行通讯,支持及时通讯 不能很好地处理处罚高并发的情况,不支持RPC,由于数据通过Message传输,因此只能传输Bundle支持的数据范例 低并发的一对多及时通讯,无RPC需求,大概无须要返回效果的RPC需求
-ContentProvider支持一对多的及时并发通讯,在数据源共享方面功能强大,可通过Call方法扩展别的操纵 可以明确为受束缚的AIDL,主要提供对数据源的CRUD操纵 一对多的历程间数据共享
- BroadcastReceiver操纵简单,对持一对多及时通讯 只支持数据单向通报,效率低且安全性不高 一对多的低频率单向通讯
- Socket功能强大,可通过网络传输字节流,支持一对多及时并发通讯 实现细节步调稍繁琐,不支持直接的RPC 网络间的数据交换
websocket 和 http相关
- 什么是 websocket?
websocket是HTML5的一种新协议,答应服务器想客户端通报信息,实现浏览器和客户端双工通讯。
- websocket特点
(1)与http协议有精良的兼容性;
(2)创建在TCP协议之上,和http协议同属于应用层;
(3)数据格式比力轻量,性能开销小,通讯高效;
(4)可以发送文本,也可以发送二进制;
(5)没有同源限定,可以与任意服务器通讯。
- http和websocket的区别
3.1 http协议是短链接,因为哀求之后,都会关闭毗连,下次哀求须要重新打开链接。
3.2 websocket协议是一种长毗连,只须要通过一次哀求来初始化毗连,然后全部哀求和相应都是通过TCP链接举行通讯。
- 特点
最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向同等对话,属于服务器推送技术的一种。
其他特点包罗:
(1)创建在 TCP 协议之上,服务器端的实现比力容易。
(2)与 HTTP 协议有着精良的兼容性。默认端口也是80和443,而且握手阶段接纳 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 署理服务器。
(3)数据格式比力轻量,性能开销小,通讯高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限定,客户端可以与任意服务器通讯。
(6)协议标识符是ws(假如加密,则为wss),服务器网址就是 URL
连续更新中 ... |