1. Android线程安全
    Android一般情况下会使用一个主线程控制UI,非主线程无法控制UI,Android4.0以后在主线程中进行网络操作,所有的网络操作在独立的线程中异步运行

  2. android使用返回栈来控制活动
    每个活动生命周期内有四个活动状态,运行状态(栈顶就是运行 可见状态),暂停状态(不位于栈顶,但任然可见),停止状态(不栈顶,完全不可见),销毁状态(从返回栈中移除)

Activity定义了7个回调方法,覆盖活动生命周期的每一个环节
onCreate() 初始化布局,绑定事件
onStart() 活动由不可见变为可见时候调用
onResume() 活动准备交互时候调用
onPause() 活动启动或调用另一个活动时(对话框活动启动)
onStop() 活动完全不可见
onDestory() 活动销毁前调用
onRestart() 活动由停止变为运行
完整生命周期 onCreate()---onDestory()
可见生命周期 onStart()---onStop() 可能无法交互
前台生命周期 onResume()---onPause() 可交互 运行状态

Activity四种启动模式
1.standard 默认进入Activity所属返回栈中 不管是否存在于返回栈中,每次启动都创建一个新的实例
2.singleTop 栈顶复用模式 如果位于栈顶不创建新的实例(Activity不会被重新创建)
3.singleTask 栈内复用模式 解决重复创建栈顶,如果返回栈中有就直接使用,这个活动之上的活动全部出栈
没有就创建一个新的实例
4.singleInstance 单实例模式 在manifiest的里设置android:launchMode="singleInstance"
这样创建单独的返回栈来管理此活动,可以允许其他程序调用
注意:默认情况下,所有activity所需的任务栈的名字为应用的包名,可以通过给activity指定TaskAffinity属性来指定任务栈,这个属性值不能和包名相同,否则就没有意义 。

随时随地退出活动
public class ActivityCollector{
//指定泛型
public static List activities=new ArrayList();
public static void addActivity(){
activities.add(activity);
}
public static void removeActivity(){
activities.remove(activity);
}
public static void removeAll(){
for(Activity activity:activities){
if(!activity.isFinishing()){
activity.finish();
}
}
}
}

//List暂存活动,removeAll()将活动全部销毁掉

使用在onCreate(){
ActivityCollector.addActivity(this);
}
在protected void onDestory(){
ActivityCollector.removeActivity(this);
}
switch(v.getId()){
case R.id.button:
ActivityCollector.removeAll();
break;
default:
break;
}

Service的生命周期 (bind和start的区别) Service是专门在后台处理长时间耗时任务的Android组件,没有UI,有两种启动方式
startService 只是startService,启动serivce的组件(如Activity)与Service并没有关联,只要调用service的stopSelf或者组件调用StopService才会停止服务
生命周期
onCreate()->onStartComand()->service is running->onDestory()
bindService方法创建Service,其他组件通过回调Service代理对象与Service交互,两者也进行绑定,启动方被销毁时service自动调用unBind方法解除绑定,当所有绑定被解除时,Service才被销毁

Service的onCreate是在主线程中调用的,不能进行耗时操作会阻塞UI线程

Service 使用时一定要注册 Android的四大组件都需要注册(Activity Service BroadCastReceive广播 ContentProvider内容提供器 )

是否知道IntentService,在什么场景下使用IntentService?

Service应用场景:如果一个应用要从网络上下载MP3文件,并在Activity上展示进度条,这个Activity要求是可以转屏的。那么在转屏时Actvitiy会重启,如何保证下载的进度条能正确展示进度呢?
解决:通过Service,不过涉及到Service与Activity交互

适合执行那些不需要和用户交互而且还要长时间执行的任务,服务默认运行于主线程,需要手动创建子线程执行具体的任务,否则出现主线程被阻塞

要针对实际场景具体分析是否使用Service,因为Service也是在主线程中调用,还是要开线程才能处理长时间操作,Service与UI交互也不简单,如果只是进行一些耗时操作而且在界面退出改变时,工作也停止,这样直接使用Thread,Asynctask,ThreadHandler更加简单

碎片生命周期和回调
生命周期的四个状态:运行状态,暂停状态,停止状态,销毁状态
运行状态:碎片可见而且与它关联的活动也处于运行状态
暂停状态:活动进入暂停状态(比如一个未占满屏幕的活动被添加到栈顶),与它相关联的可见碎片也进入暂停状态
停止状态:当相关联的活动进入停止状态,或者通过调用FragmentTransaction的remove(),replace(),将碎片从活动中移除,停止状态的碎片完全不可见可能被系统回收
销毁状态:相关联的活动呗销毁,或者调用FragmentTrasaction的remove(),replace(),将碎片从活动中移除,或者事务提交之前调用addToBackStack()方法,碎片都会进入停止状态

Fragemnt定义了一系列回调方法覆盖碎片生命周期的每一个环节
除了活动中的回调方法,Fragment还有附加的回调方法
1.onAttach()
在碎片和活动建立关联的时候调用
2.onCreateView()
为碎片加载布局时候调用
3.onActivityCreated()
与碎片相关联的活动创建完毕时候调用
4.onDestoryView()
与碎片相关联的视图被移除时候调用
5.onDetech()
当碎片与活动解除关联时候调用
onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume()->
碎片已经激活->(用户点击返回键,或者碎片被移除/替换,或者碎片被添加到返回栈)->onPause()->onStop()->onDestoryView()(从返回栈中回到上一个碎片)->onDestory()->onDetech->碎片被销毁

Fragment和Activity生命周期的关系
创建过程
F onAttach()
F onCreate()
F onCreateView()
A onCrete()
F onActivityCreated()
A onStart()
F onStart()
A onResume()
F onResume()
销毁过程
F onPause()
A onPause()
F onStop()
A onStop()
F onDestroyView()
F onDestory()
F onDetach()
A onDestory()

Activity 与meun创建顺序
在Activity回调onResume()后创建menu,再调用onCreateOptionMenu()

重要
面试官要看的点,真正的项目需要一个开发人员对某个问题有一定的深度,也需要对整个Android的知识点有一定的广度。深度代表这个人对问题认真对待有钻研的精神,广度代表这个人在面对同一个问题时,会更容易从多种可行的方案中选出最合适的一种。

AIDL(Android Interface Defination Language) Android进程间通信(IPC) 也就是两个应用程序间通信

AsyncTask(原理也是基于异步消息处理机制) Android做了很好的封装
AsyncTask是一个抽象类,需要创建一个子类去继承他,需要指定三个泛型参数
1.params 执行AsyncTask需要传入的参数,可以在后台任务中使用
2.Process 后台执行任务,需要在界面上显示当前进度,把该 泛型 作为进度单位
3.Result 任务执行完毕,指定泛型作为返回值
class DownloanTask extends AsyncTask

需要重写四个方法
1.onPreExecute()
任务执行之前调用,进行一些初始化操作,比如显示一条进度条对话框
2.doInBackground(Params...)
所有代码都在子线程中运行,在这里处理一些耗时操作,通过return将任务执行结果返回,
如果第三个泛型参数为Void不用返回结果
注意:不能更新UI,如果需要调用publish(Progress...)方法来完成
3.onProgressUpdate(Progress...) OP
如果后台调用publishProgress()方法,就会执行该方法,通过后台传入的值更新UI
4.onPostExecute(Result)
当后台执行任务结束,并通过return 语句返回时调用,返回的数据作为参数,可以进行一些UI操作比如提醒任务执行结果、关闭掉进度条等

内存泄露(内存溢出)和OOM(Out of Memory 内存溢出)
1.Android(Java)中常见的容易引起内存泄漏的不良代码
Android应用于嵌入式设备,由于内存和配置的限制,如果代码有太多的对内存使用不当的地方,会照成设备运行缓慢或者死机。为了使应用程序安全且快速的运行,Android 的每个应用程序都会使用一个专有的Dalvik虚拟机实例来运行,也就是说每个应用程序都是在属于自己的进程中运行的。一方面,如果程序在运行过程中出现了内存泄漏的问题,仅仅会使得自己的进程被kill掉,而不会影响其他进程(如果是system_process 等系统进程出问题的话,则会引起系统重启)。另一方面Android为不同类型的进程分配了不同的内存使用上限,如果应用进程使用的内存超过了这个上限,则会被系统视为内存泄漏,从而被kill掉。

  1. 内存不够用就叫oom.
    Android设备内存一般比较小,容易引起oom.
    Android每个应用程序在专有的Dalvik虚拟机实例中运行,Android分配固定内存。超出分配的内存,引起oom,系统KILL掉,程序结束。
    Android系统进程OOM,机器重启。
    出现oom,无非主要是以下几个方面:
      一、加载对象过大
      二、相应资源过多,没有来不及释放。
      解决这样的问题,也有一下几个方面:
      一:在内存引用上做些处理,常用的有软引用、强化引用、弱引用
      二:在内存中加载图片时直接在内存中做处理,如:边界压缩.
      三:动态回收内存
      四:优化Dalvik虚拟机的堆内存分配
      五:自定义堆内存大小

SQLite 使用 SQL(Structured Query Language)
SQLite提供了一个SQLiteOpenHelper来操作数据库,新建一个子类继承
重写构造方法有四个参数 context,name,factory(查询数据返回自定义的Cursor一般为null),version
在重写onCrete() onUpdate()方法(如果数据库表中存在表,需要使用更新)

构建完SQLiteOpenHelper实例以后,调用getReadableDatabase()和getWritableDataBase()方法就会创建数据库 文件位置/data/data/package name/databases/目录下

数据库的操作 CURD()
getReadableDatabase()返回一个SQLiteDatabase对象,借助这个对象就可以进行CURD操作

insert()插入数据 三个参数 1.表名2.未指定数值赋值为null(null)3. ContentValues对象
提供了一系列方法向列中添加数据
ContentValues values=new ContentValues();
values.put("name","book");
values.put("pages",456);
db.insert("Book",null,values);

update() 更新数据 4个参数 1.表名 2. ContentValues 3.4.约定某一行或某几行(不指定更新所有行)
values.put("price",10.99);
db.update("Book",values,"name=?",new String[] {"My Real Story"});
第三个参数相当于where语句 where bookname="My Real Story"

delete() 删除数据 三个参数1.表名 2.3.约定某一行或某几行(不指定删除所有行数据)

db.delete("Book","page>?",new String[]{"500"})

query() 7/8个参数 1.表名 2.约定查询那几列(没有就所有列)3.4.参数约定那几行
5.指定groupby的列 6.group by 后进一步过滤7.设置排序方式

Cursor cursor=db.query("Book",null,null,null,null,null,null);
if(cursor.moveToFirst){//移动到第一行
do{
String name=cursor.getString(cursor.getColumnIdex("name"));//获取某一列的索引位置,再读取数据
int page=cursor.getInt(sursor.getColumnIndex("pages"));
}
cursor.close();
}

Android-universal-Image-Loader
实现了异步的网络图片加载,并且支持多线程异步加载

Fresco内存管理
Image Pipeline:从网络或者本地文件加载图片(设计三级缓存,2级内存,1级文件,最大节省内存和CPU)
Drawees模块:方便显示loadding图,图片不显示时及时释放内存
解压后的图片既Bitmap,占用大量的内存,大内存引发频繁的GC,Android5.0以下会造成卡顿,
Fresco将图片放到特殊的内存区域,图片不显示时内存自动释放,使APP运行更加流畅,减少因图片内存占用引发的OOM
Fresco会显示渐进式图片,就是显示图片的大致轮廓,随着图片的下载逐渐清晰(只需要提供URI)
支持加载gif,自定义居中,圆角图,加载失败点击重新加载,自定义占位图,自定义按压的占位图
从远端加载或者从缓存中读取,加载完成回调通知,缩放或旋转图片。

在setContentView前,进行初始化
Fresco.initialize(context);
2)layOut中加入simpleDraweeView
android:id="@+id/my_image_view"
android:layout_width="20dp"
android:layout_height="20dp"
fresco:placeholderImage="@drawable/my_drawable"
/>
3)加载图片
Uri uri=Uri.prase("http://");
SimpleDraweeView darwview=()findViewById();
drawview.setImageView(uri)


http访问网络


  1. 继承Service
  2. 在manifest中注册
  3. 调用context的bindService(intent,ServiceConnection,int)
  4. 不再使用时调用unbinService(ServiceConnection)方法停止服务
    Service生命周期
    onBind()方法返回一个IBinder接口,IBinder是组件与Service通信的桥梁
    组件获取IBinder接口就可以调用Service中的方法
    onCreate->onBind()->unBind()->onDestory()

IntentService是Service的子类,用来处理多个请求,因为Service通常处理一个请求,创建独立的线程处理请求,调用onHandlerIntent()方法处理按时间排序的请求队列。


BroadCastReceiver
广播分为两种类型,有序广播和无序广播,无序广播是异步的传播效率快,但是上一个接受者不能将处理结果传递给下一个接受者,无法中止Intent的传播,有序广播在Intent-filter的android:priority设置优先级
Context.sendBroadCast();
Context.sendOrderedBroadcast();

  • 有序:上一个接受者setResultExtras(Bundle)方法存入结果对象,
    下一个接受者调用Bundle bundle=getResultExtra(Bundle)获取上一个接受者存入结果中的对象的数据
    调用对象->实现onReceiver->结束

步奏

  1. 继承BroadcastReceiver
  2. 重写onReceive方法
  3. 在manifest.xml中注册
    BroadcastReceiver生命周期很短,执行完onReceiver以后就结束
  • xml注册
    //这里自定义一个广播动作
  • 动态注册
    registerReceiver(new MyBroadcastReceiver(),new IntentFilter("test"));
    一定要加上

发送广播
Intent intent=new Intent("test");
sendBroadCast(intent);

静态注册与动态注册的区别

  • 动态注册广播不是常驻型,广播跟随着Activiy的生命周期
    Activity结束前要移除广播接收器
  • 静态注册是常驻型,应用程序关闭如果有广播来,程序会被系统调用自动运行
    在AndroidManifest注册,应用程序关闭也会接收到广播

ContentProvider

ContentProvider是Android中跨程序共享数据的组件,为数据提供外部访问接口,被访问的数据主要以数据库的形式存在,可以选择共享那一部分数据,隐私数据不贡献从而更加安全。

  • 使用系统的ContentProvider(通话记录,短信,通讯录)
    步骤
  1. 获取ContentResolver实例。
  2. 确定Uri的内容,并解析成Uri实例
  3. 通过ContentResolver实例调用相应的方法,传递相应的参数,但第一个参数是Uri
  • 自定义ContentProvider
    resolver(内容操作器)操作数据的方法与sqlitedatabase的真删改查,因为他们操作数据都是以数据库格式存储的。
    resolver利用URI定位数据的位置,而sqlite方法第一个参数是数据库表名定位数据(resolver跨程序共享,不同程序可能有同名的表)
  1. Uri.prase(Uri字符串)->解析成Uri对象
  2. 传给resolver相应的真删改查方法

自定义时重写6个方法:

  • oncreate() contentprovider创建时提供的方法,负责数据库的创建和更新
  • query()
  • update()
  • insert()
  • delete()
  • gettype()

Intent对象保存了消息的内容,包括请求的操作名称和待操作数据的URI,
Intent不仅仅应用于程序之间,用于Service和Intent,Android根据Intent的描述找到对应的组件,将Intent传递给组件,完成组件的调用

后台Activity被回收如何恢复

重写onSaveInstanceState()方法,在此方法中保存需要的数据,在activity回收之前被调用,通过重写onRestoreInstanceState()提取保存的数据。

更多相关文章

  1. Android中native进程内存泄露的调试技巧
  2. 解决方法:Eclipse的 window-->preferences里面没有Android选项
  3. GalHttprequest类库简介——android平台上的一个轻量级的http网
  4. Android之数据存储详解(二)之SQLite数据库存储数据
  5. Android(安卓)AudioTrack分析
  6. Android中Fragment的应用(android官方教程完美翻译)
  7. android intent和intent action大全
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. Android应用于军事制造业,开放性优势受青
  2. android wifi设置
  3. Android(安卓)Binder 机制初步学习 笔记(
  4. Android(安卓)开发中C++链接C库
  5. Android Studio共用Eclipse的Android项目
  6. HNU_团队项目_Android和数据库对接出现问
  7. Android API中常用的包
  8. 使用Android(安卓)sdk/build-tools/dx工
  9. Android 渗透测试学习手册(七)不太知名的 A
  10. Android必备知识(五)多线程及AsyncTask