整理的常见的问题 http://chenfuduo.me

整理来自这里

水平有限,有错误请提出来。

Android常见的问题

标签(空格分隔): 移动开发


  • 常见算法问题的 Java 实现

资料可见

算法介绍可见

算法是很多公司面试必须,国内 BAT 基本面试中都会有,尤以百度为盛。


  • 常见设计模式的 Java 实现

资料可见


  • Android 开源项目源码解析

资料可见

Android 开源项目源码解析网页版。反正只要是面高级开发者,我都会问他项目中使用的库原理,这是我对高级开发者一般的要求。

国内中大型的公司及优秀创业公司都比较看重原理,重知其然知其所以然。


  • 遇到问题你可以@的那些 Android 开发者

碰到问题,首先我们建议 Google,无果可 @ GitHub 上的 Android 开发者(好像我暴露他们了( ⊙ o ⊙ ))。


  • Java 基础之 String、StringBuilder、StringBuffer、CharSequence 区别

两个比较好的回答:

NO1

1) CharSequence接口:是一个字符序列.String StringBuilder 和 StringBuffer都实现了它. 2) String类:是常量,不可变. 3) StringBuilder类;只可以在单线程的情况下进行修改(线程不安全). 4) StringBuffer类:可以在多线程的情况下进行改变(线程安全). 5)Stringbuilder比StringBuffer效率高,应该尽量使用StringBuilder.

NO2

1.CharSequence是一个java接口,代表一个char序列,String、StringBuilder、StringBuffer都实现了该接口,CharSequence实例通过调用toString方法可转化为String对象。 2.String类是final的,不可派生子类,其内部封装的是char[],另外,android下的String类和jdk中的String类是有区别的,android下的String类中部分API通过native方法实现,效率相对高一些。 3.String使用’+’进行字符串拼接时,在编译期会转化为StringBuilder#append方式 4.String在内存中有一个常量池,两个相同的串在池中只有一份实例(String s = “abc”方式或者String#intern方式会在池中分配),使用new String方式会在heap中分配,每次创建都是一个全新的实例。 5.StrigBuilder & StringBuffer都是可扩展的串,提供了一系列apped方法用于拼接不同类型对象 6.StringBuffer于jdk1.0引入,线程安全(多线程场景下使用),StringBuilder于jdk1.5引入,线程不安全,因而效率更高。 7.StringBuilder & StringBuffer初始容量都为16,开发者应该指定其容量,以避免多次扩容所带来的性能问题。


  • Java 基础之继承与接口的区别
  • 抽象类:

抽象类体现了数据抽象的思想,是实现多态的一种机制。它定义了一组抽象的方法,至于这组抽象方法的具体表现形式由派生类来实现。同时抽象类提供了继承的概念,它的出发点就是为了继承,否则它没有存在的任何意义。所以说定义的抽象类一定是用来继承的,同时在一个以抽象类为节点的继承关系等级链中,叶子节点一定是具体的实现类。 在语法方面: 1.由abstract关键词修饰的类称之为抽象类。 2.抽象类中没有实现的方法称之为抽象方法,也需要加关键字abstract。 3.抽象类中也可以没有抽象方法,比如HttpServlet方法。 4.抽象类中可以有已经实现的方法,可以定义成员变量。

  • 接口: 接口是用来建立类与类之间的协议,它所提供的只是一种形式,而没有具体的实现。同时实现该接口的实现类必须要实现该接口的所有方法,通过使用implements关键字。 接口是抽象类的延伸,java为了保证数据安全是不能多重继承的,也就是说继承只能存在一个父类,但是接口不同,一个类可以同时实现多个接口,不管这些接口之间有没有关系,所以接口弥补了抽象类不能多重继承的缺陷, 语法方面: 1.由interface关键词修饰的称之为接口; 2.接口中可以定义成员变量,但是这些成员变量默认都是public static final的常量。 3.接口中没有已经实现的方法,全部是抽象方法。 4.一个类实现某一接口,必须实现接口中定义的所有方法。 5.一个类可以实现多个接口。

区别: 一.语法层次上:如上所述。 二.设计层次上: 1、 抽象层次不同。抽象类是对类抽象,而接口是对行为的抽象。抽象类是对整个类整体进行抽象,包括属性、行为,但是接口却是对类局部(行为)进行抽象。 2、 跨域不同。抽象类所跨域的是具有相似特点的类,而接口却可以跨域不同的类。我们知道抽象类是从子类中发现公共部分,然后泛化成抽象类,子类继承该父类即可,但是接口不同。实现它的子类可以不存在任何关系,共同之处。例如猫、狗可以抽象成一个动物类抽象类,具备叫的方法。鸟、飞机可以实现飞Fly接口,具备飞的行为,这里我们总不能将鸟、飞机共用一个父类吧!所以说抽象类所体现的是一种继承关系,要想使得继承关系合理,父类和派生类之间必须存在”is-a” 关系,即父类和派生类在概念本质上应该是相同的。对于接口则不然,并不要求接口的实现者和接口定义在概念本质上是一致的, 仅仅是实现了接口定义的契约而已,相当于是”like-a”的关系。 3、 设计层次不同。对于抽象类而言,它是自下而上来设计的,我们要先知道子类才能抽象出父类,而接口则不同,它根本就不需要知道子类的存在,只需要定义一个规则即可,至于什么子类、什么时候怎么实现它一概不知。比如我们只有一个猫类在这里,如果你这是就抽象成一个动物类,是不是设计有点儿过度?我们起码要有两个动物类,猫、狗在这里,我们在抽象他们的共同点形成动物抽象类吧!所以说抽象类往往都是通过重构而来的!但是接口就不同,比如说飞,我们根本就不知道会有什么东西来实现这个飞接口,怎么实现也不得而知,我们要做的就是事前定义好飞的行为接口。所以说抽象类是自底向上抽象而来的,接口是自顶向下设计出来的。

附加,空接口的作用: 通常是作为一个标记,你比如这个Serializable、Cloneable。


  • Android开发中何时使用多进程

要想知道如何使用多进程,先要知道Android里的多进程概念。一般情况下,一个应用程序就是一个进程,这个进程名称就是应用程序包名。我们知道进程是系统分配资源和调度的基本单位,所以每个进程都有自己独立的资源和内存空间,别的进程是不能任意访问其他进程的内存和资源的。那如何让自己的应用拥有多个进程?很简单,我们的四大组件在AndroidManifest文件中注册的时候,有个属性是android:process:

  • 这里可以指定组件的所处的进程。默认就是应用的主进程。指定为别的进程之后,系统在启动这个组件的时候,就先创建(如果还没创建的话)这个进程,然后再创建该组件。你可以重载Application类的onCreate方法,打印出它的进程名称,就可以清楚的看见了。再设置android:process属性时候,有个地方需要注意:如果是android:process=”:deamon”,以:开头的名字,则表示这是一个应用程序的私有进程,否则它是一个全局进程。私有进程的进程名称是会在冒号前自动加上包名,而全局进程则不会。一般我们都是有私有进程,很少使用全局进程。他们的具体区别不知道有没有谁能补充一下。源文档地址

  • 使用多进程显而易见的好处就是分担主进程的内存压力。我们的应用越做越大,内存越来越多,将一些独立的组件放到不同的进程,它就不占用主进程的内存空间了。当然还有其他好处,有心人会发现Android后台进程里有很多应用是多个进程的,因为它们要常驻后台,特别是即时通讯或者社交应用,不过现在多进程已经被用烂了。典型用法是在启动一个不可见的轻量级私有进程,在后台收发消息,或者做一些耗时的事情,或者开机启动这个进程,然后做监听等。还有就是防止主进程被杀守护进程,守护进程和主进程之间相互监视,有一方被杀就重新启动它。应该还有还有其他好处,这里就不多说了。

  • 坏处的话,多占用了系统的空间,大家都这么用的话系统内存很容易占满而导致卡顿。消耗用户的电量。应用程序架构会变复杂,应为要处理多进程之间的通信。这里又是另外一个问题了。


  • 设备横竖屏切换的时候,接下来会发生什么

我们一般看到的答案:

  • 不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次

  • 设置Activity的android:configChanges=”orientation”时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次

  • 设置Activity的android:configChanges=”orientation|keyboardHidden”时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法

这个是不完整的。下面的文字引自Android Developer:

Caution: Beginning with Android 3.2 (API level 13), the "screen size"also changes when the device switches between portrait and landscape orientation. Thus, if you want to prevent runtime restarts due to orientation change when developing for API level 13 or higher (as declared by the minSdkVersion and targetSdkVersion attributes), you must include the “screenSize” value in addition to the “orientation” value. That is, you must decalare android:configChanges=”orientation|screenSize”. However, if your application targets API level 12 or lower, then your activity always handles this configuration change itself (this configuration change does not restart your activity, even when running on an Android 3.2 or higher device).

也就是说:当API >12时,需要加入screenSize属性,否则屏幕切换时即使你设置了orientation系统也会重建Activity.

横竖屏切换对生命周期的影响

Activity在清单文件中的属性


  • 要做一个尽可量流畅的ListView,你可以做到的优化手段是什么?越详细越多手段越好
  • 复用convertView
  • 使用ViewHolder
  • item中有图片时,异步加载
  • 快速滑动时,不加载图片
  • item中有图片时,应对图片进行适当压缩
  • 分批和分页加载

facebook新闻页ListView优化


  • java虚拟机的运行原理

参见这里的文档


  • 继承viewGroup后必须实现哪些方法,这些方法有谁调用

继承ViewGroup后,IDE会提示提供构造方法和实现onLayout()方法。

在ViewGroup中只有一个抽象的方法onLayout(),所以必须实现它;如果执行requestLayout()请求重新调整位置会调用到onLayout()

ViewGroup深入理解


  • android 关于安全的问题,你所知道的所有的安全问题
  • 错误导出组件
  • 参数校验不严
  • WebView引入各种安全问题
  • 不混淆、不防二次打包
  • 明文存储关键信息
  • 错误使用HTTPS
  • 山寨加密方法

Security Tips


  • 对称加密和非对称加密

对称加密,就是加密和解密数据都是使用同一个key,这方面的算法有DES。 非对称加密,加密和解密是使用不同的key。发送数据之前要先和服务端约定生成公钥和私钥,使用公钥加密的数据可以用私钥解密,反之。这方面的算法有RSA。ssh 和 ssl都是典型的非对称加密。

对称加密 非对称加密


  • Activity的四种launchMode

Activity一共有以下四种launchMode:

  • standard
  • singleTop
  • singleTask
  • singleInstance

我们可以在AndroidManifest.xml配置的android:launchMode属性为以上四种之一即可。 下面我们结合实例一一介绍这四种lanchMode: 1.standard standard模式是默认的启动模式,不用为配置android:launchMode属性即可,当然也可以指定值为standard。standard启动模式,不管有没有已存在的实例,都生成新的实例。

2.singleTop 我们在上面的基础上为指定属性android:launchMode=”singleTop”,系统就会按照singleTop启动模式处理跳转行为。跳转时系统会先在栈结构中寻找是否有一个Activity实例正位于栈顶,如果有则不再生成新的,而是直接使用。如果系统发现存在有Activity实例,但不是位于栈顶,重新生成一个实例。 这就是singleTop启动模式,如果发现有对应的Activity实例正位于栈顶,则重复利用,不再生成新的实例。

3.singleTask 如果发现有对应的Activity实例,则使此Activity实例之上的其他Activity实例统统出栈,使此Activity实例成为栈顶对象,显示到幕前。

4.singleInstance 这种启动模式比较特殊,因为它会启用一个新的栈结构,将Acitvity放置于这个新的栈结构中,并保证不再有其他Activity实例进入。


  • Android启动Service的两种方式是什么? 它们的适用情况是什么
  • startService:生命周期与调用者不同。启动后若调用者未调用stopService而直接退出,Service仍会运行
  • bindService:生命周期与调用者绑定,调用者一旦退出,Service就会调用unBind->onDestroy

  • 谈谈你对Android中Context的理解

参考下面的文章


  • Java中反射的作用是什么?什么时候会用到

JAVA反射机制是在#运行时#,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 Java反射机制主要提供了以下功能: a)在运行时判断任意一个对象所属的类; b)在运行时构造任意一个类的对象; c)在运行时判断任意一个类所具有的成员变量和方法; d)在运行时调用任意一个对象的方法;生成动态代理。


  • 注册广播有几种方式,这些方式有何优缺点?请谈谈Android引入广播机制的用意

1.在清单文件中注册, 常见的有监听设备启动,常驻注册不会随程序生命周期改变 2.在代码中注册,随着程序的结束,也就停止接受广播了

Android引入广播机制的用意:

a:从MVC的角度考虑(应用程序内) 其实回答这个问题的时候还可以这样问,android为什么要有那4大组件,现在的移动开发模型基本上也是照搬的web那一套MVC架构,只不过是改了点嫁妆而已。android的四大组件本质上就是为了实现移动或者说嵌入式设备上的MVC架构,它们之间有时候是一种相互依存的关系,有时候又是一种补充关系,引入广播机制可以方便几大组件的信息和数据交互。

b:程序间互通消息(例如在自己的应用程序内监听系统来电)

c:效率上(参考UDP的广播协议在局域网的方便性)

d:设计模式上(反转控制的一种应用,类似监听者模式)


  • Java中有内存泄露吗?举一些例子?JNI中呢

1.查询数据库没有关闭游标 2. 构造Adapter时,没有使用缓存的 convertView 3. Bitmap对象不再使用时调用recycle()释放内存 4. 无用时没有释放对象的引用 5. 在Activity中使用非静态的内部类,并开启一个长时间运行的线程,因为内部类持有Activity的引用,会导致Activity本来可以被gc时却长期得不到回收 6.使用Handler处理消息前,Activity通过例如finish()退出,导致内存泄漏 7.动态注册广播在Activity销毁前没有unregisterReceiver

Android内存泄漏研究


  • 请介绍下Android中常用的五种布局

我常用的:linearlayout,RelativeLayout,FrameLayoutTableLayout很少用到,GridLayout用过一次。


  • 请介绍下Android的数据存储方式

google官方的数据存储方式的定义共有五种:

  • sharedPreference
  • 内存存储
  • 外部存储(其实就是文件存储)
  • SQlite
  • 网络存储

官方链接


  • Service的onCreate回调在UI线程中吗

Service生命周期的各个回调和其他的应用组件一样,是跑在主线程中,会影响到你的UI操作或者阻塞主线程中的其他事情


  • 请介绍下ContentProvider是如何实现数据共享的

当一个应用程序需要把自己的数据暴露给其他程序使用时,该就用程序就可通过提供ContentProvider来实现;其他应用程序就可通过ContentResolver来操作ContentProvider暴露的数据。 一旦某个应用程序通过ContentProvider暴露了自己的数据操作接口,那么不管该应用程序是否启动,其他应用程序都可以通过该接口来操作该应用程序的内部数据,包括增加数据、删除数据、修改数据、查询数据等。 ContentProvider以某种Uri的形式对外提供数据,允许其他应用访问或修改数据;其他应用程序使用ContentResolver根据Uri去访问操作指定数据。 步骤: 1、定义自己的ContentProvider类,该类需要继承Android提供的ContentProvider基类。 2、在AndroidManifest.xml文件中注册个ContentProvider,注册ContenProvider时需要为它绑定一个URL。 例: android:authorities=”com.myit.providers.MyProvider” /> 说明:authorities就相当于为该ContentProvider指定URL。 注册后,其他应用程序就可以通过该Uri来访问MyProvider所暴露的数据了。

接下来,使用ContentResolver操作数据,Context提供了如下方法来获取ContentResolver对象。 一般来说,ContentProvider是单例模式,当多个应用程序通过ContentResolver来操作 ContentProvider提供的数据时,ContentResolver调用的数据操作将会委托给同一个ContentProvider处理。 使用ContentResolver操作数据只需两步: 1、调用Activity的ContentResolver获取ContentResolver对象。 2、根据需要调用ContentResolver的insert()、delete()、update()和query()方法操作数据即可.


  • 请介绍下AsyncTask的内部实现,适用的场景是

Android AsyncTask完全解析,带你从源码的角度彻底理解

AsyncTask内部也是Handler机制来完成的,只不过Android提供了执行框架来提供线程池来执行相应地任务,因为线程池的大小问题,所以AsyncTask只应该用来执行耗时时间较短的任务,比如HTTP请求,大规模的下载和数据库的更改不适用于AsyncTask,因为会导致线程池堵塞,没有线程来执行其他的任务,导致的情形是会发生AsyncTask根本执行不了的问题。


  • 谈谈你对binder机制的理解

Android进程间通信(IPC)机制Binder简要介绍和学习计划 bind service

binder是一种IPC机制,进程间通讯的一种工具.

Java层可以利用aidl工具来实现相应的接口.


  • Android中进程间通信有哪些实现方式?原理是什么

Intent,Binder(AIDL),Messenger,BroadcastReceiver


  • 介绍下实现一个自定义view的基本流程

1.明确需求,确定你想实现的效果 2.确定是使用组合控件的形式还是全新自定义的形式,组合控件即使用多个系统控件来合成一个新控件,你比如titilebar,这种形式相对简单,参考 3.如果是完全自定义一个view的话,你首先需要考虑继承哪个类,是View呢,还是ImageView等子类。 4.根据需要去复写View#onDraw、View#onMeasure、View#onLayout方法 5.根据需要去复写dispatchTouchEvent、onTouchEvent方法 6.根据需要为你的自定义view提供自定义属性,即编写attr.xml,然后在代码中通过TypedArray等类获取到自定义属性值 7.需要处理滑动冲突、像素转换等问题

另外一个回答

  • 编写attr.xml文件
  • 在layout布局文件中引用,同时引用命名空间
  • 在自定义控件中进行读取(构造方法拿到attr.xml文件值)
  • 覆写onMeasure()方法
  • 覆写onLayout()方法

  • Android中touch事件的传递机制是怎样的?

事件传递:

基础知识

(1) 所有Touch事件都被封装成了MotionEvent对象,包括Touch的位置、时间、历史记录以及第几个手指(多指触摸)等。

(2) 事件类型分为ACTION_DOWN, ACTION_UP, ACTION_MOVE, ACTION_POINTER_DOWN, ACTION_POINTER_UP, ACTION_CANCEL,每个事件都是以ACTION_DOWN开始ACTION_UP结束。

(3) 对事件的处理包括三类,分别为传递——dispatchTouchEvent()函数、拦截——onInterceptTouchEvent()函数、消费——onTouchEvent()函数和OnTouchListener

传递流程

(1) 事件从Activity.dispatchTouchEvent()开始传递,只要没有被停止或拦截,从最上层的View(ViewGroup)开始一直往下(子View)传递。子View可以通过onTouchEvent()对事件进行处理。

(2) 事件由父View(ViewGroup)传递给子View,ViewGroup可以通过onInterceptTouchEvent()对事件做拦截,停止其往下传递。

(3) 如果事件从上往下传递过程中一直没有被停止,且最底层子View没有消费事件,事件会反向往上传递,这时父View(ViewGroup)可以进行消费,如果还是没有被消费的话,最后会到Activity的onTouchEvent()函数。

(4) 如果View没有对ACTION_DOWN进行消费,之后的其他事件不会传递过来。

(5) OnTouchListener优先于onTouchEvent()对事件进行消费。 上面的消费即表示相应函数返回值为true。

PRE_andevcon_mastering-the-android-touch-system Touch 事件的分发和消费机制


  • ANR是什么?怎样避免和解决ANR

ANR:Application Not Responding,即应用无响应

ANR一般有三种类型:

1:KeyDispatchTimeout(5 seconds) –主要类型

按键或触摸事件在特定时间内无响应

2:BroadcastTimeout(10 seconds)

BroadcastReceiver在特定时间内无法处理完成

3:ServiceTimeout(20 seconds) –小概率类型

Service在特定的时间内无法处理完成

超时的原因一般有两种:

(1)当前的事件没有机会得到处理(UI线程正在处理前一个事件没有及时完成或者looper被某种原因阻塞住)

(2)当前的事件正在处理,但没有及时完成

UI线程尽量只做跟UI相关的工作,耗时的工作(数据库操作,I/O,连接网络或者其他可能阻碍UI线程的操作)放入单独的线程处理,尽量用Handler来处理UI thread和thread之间的交互。

UI线程主要包括如下:

  • Activity:onCreate(), onResume(), onDestroy(), onKeyDown(), onClick()

  • AsyncTask: onPreExecute(), onProgressUpdate(), onPostExecute(), onCancel()

  • Mainthread handler: handleMessage(), post(runnable r)

查找ANR的方式: 1. 导出/data/data/anr/traces.txt,找出函数和调用过程,分析代码 2. 通过性能LOG人肉查找


  • 值得阅读的android技术文章

值得阅读的android技术文章


  • Android多线程的实现方式有哪些?它们的优缺点和适用场景是什么

Thread & AsyncTask Thread 可以与Loop 和 Handler 共用建立消息处理队列 AsyncTask 可以作为线程池并行处理多任务


  • Android下解决滑动冲突的常见思路是什么

相关的滑动组件 重写onInterceptTouchEvent,然后判断根据xy值,来决定是否要拦截当前操作

Android Touch事件传递机制 Android 事件分发机制详解


  • 如何把一个应用设置为系统应用

成为系统应用,首先要在 对应设备的 Android 源码SDK下编译,编译好之后:

  • 此 Android 设备是 Debug 版本,并且已经 root,直接将此 apk 用 adb 工具 push 到 system/app 或 system/priv-app 下即可。
  • 如果非 root 设备,需要编译后重新烧写设备镜像即可。
  • 有些权限(如 WRITE_SECURE_SETTINGS ),是不开放给第三方应用的,只能在对应设备源码中编译然后作为系统 app 使用。

  • Android注册广播有几种方式? 它们的适用情况是什么?

Android中有两种广播的注册方式: 1、静态注册:AndroidManifest.xml配置文件中; 2、动态注册:Java代码; 静态注册适用于全局广播;动态注册适用于局部广播;

补充一点:有些广播只能通过动态方式注册,比如时间变化事件、屏幕亮灭事件、电量变更事件,因为这些事件触发频率通常很高,如果允许后台监听,会导致进程频繁创建和销毁,从而影响系统整体性能。


  • 你看过Android Framework的代码吗?介绍一下某一个或几个模块?

我觉得这个问题 最好从app相关系统模块讲一下,例如inputmanager(输入事件),activitymanager,windowmanager等. 或者从类似asyctask,hander,等基础工具来讲.


  • 如何调试Android应用程序
  • log
  • 断点调试

  • 请用任意语言实现数据结构中的栈

  • 谈谈开发中遇见的性能优化问题,并说明是如何解决的

根据Google公开课的内容,Android性能问题大致主要以下几大类:

  • UI渲染
  • 代码执行和内存使用
  • 电池

关于如何使用AS的各种工具检测应用性能问题以及如何解决这些问题可以参考下面这些链接:


  • 谈谈 MVP 模式的优缺点

  • 本地存储的数据该怎么加密比较好。比如:shared_prefs、sqlite数据、登录用户名、密码等。如果是Aes加密的话,怎么保存key值呢

密码不要存在本地,一般保存token。最基本的要代码混淆,可以的话加壳,防止反编译。


  • android在线程中创建handler应注意什么

Looper.prepare(),主线程使用handler,系统默认prepare了,子线程中创建handler必须在前面Looper.prepare(),后面加上Looper.loop();

源码中: 主线程: 在程序启动的时候,系统已经帮我们自动调用了Looper.prepare()方法。查看ActivityThread中的main()

请注意Looper.prepareMainLooper()

子线程:

如果没有Looper.prepare().会报错:

因为没looper对象创建

looper.prepare()源码:

———我是优雅的分割线———

在Android开发中经常会使用到线程,一想到线程,一般都会想到

这样的方式。这样如果在一个Activity中多次调用上面的代码,那么将创建多个匿名线程,如果这些线程的没有被销毁,那肯定会影响性能呢。这个时候我么就想到了android提供的一个异步处理线程的类HandlerThread

一般Handler的用法

这样创建的handler是在主线程即UI线程下的Handler,即这个Handler是与UI线程下的默认Looper绑定的(当然也只有主线程才能这么干,子线程是干不了的,除非自己创建个looper)。因此,有些时候会占用ui主线程,引起一些问题,所以我们就想到了重新创建个子线程,来处理handler。。。。 使用HandlerThread解决问题

HandlerThread实际上继承于Thread,只不过它比普通的Thread多了一个Looper。我们可以使用下面的例子创建Handler

创建HandlerThread时要把它启动了,即调用start()方法。

接着就是handler的使用,如下:

创建Handler时将HandlerThread中的looper对象传入。那么这个mHandler对象就是与HandlerThread这个线程绑定了(这时就不再是与UI线程绑定了,这样它处理耗时操作将不会阻塞UI)。


  • Android Webview安全交互

Android Webview安全交互


  • Android内存泄露研究

Android内存泄露研究


  • Java程序中,全局变量和局部变量在内存的什么位置?

严谨一点应该这么问:

Java 程序在 JVM 中运行时,全局变量和局部变量在虚拟机的什么位置?

粗略回答:一个是堆一个是栈。


  • Android应用中,如何保证服务常驻内存

android service常驻内存的一点思考

首先来看原理

然后来看实现步骤