这些有些来源于网站、有些来源于本身的思考。可能有些问题网上有、可能有些问题对应的答案也有,有可能有些问题讲的不对,能指正的但愿你们不吝指教。java
Activityandroid
什么是Activity面试
四大组件之一,一个和用户交的互界面就是一个activity,是全部 View 的容器算法
Activity 生命周期sql
生命周期描述的是一个类 从建立(new出来)到死亡(垃圾回收)的过程当中会执行的方法.数据库
在这个过程当中会针对不一样的生命阶段会调用不一样的方法缓存
Activity从建立到销毁有多种状态,从一种状态到另外一种状态时会激发相应的回调方法,这些回调方法包括:安全
其实这些方法都是两两对应的,onCreate建立与onDestroy销毁;onStart可见与onStop不可见;onResume可编辑(即焦点)与onPause;服务器
还有一个onRestart方法了,在Activity被onStop后,可是没有被onDestroy,在再次启动此Activity时就调用onRestart(而再也不调用onCreate)方法;若是被onDestroy了,则是调用onCreate方法。微信
两个Activity之间跳转时必然会执行的是哪几个方法。
通常状况好比说有两个activity,分别叫A,B ,当在A里面激活B组件的时候, A 会调用 onPause()方法,而后B 调用onCreate() ,onStart(), OnResume() ,这个时候B覆盖了窗体, A会调用onStop()方法. 若是B呢 是个透明的,或者是对话框的样式, 就不会调用onStop()方法。
所以,咱们在两个activities中传递数据,或者共享资源时(如数据库链接),须要在前一个activity的onPause()方法而不是onStop()方法中进行
横竖屏切换时候Activity的生命周期。
这个生命周期跟清单文件里的配置有关系
一、不设置Activity的android:configChanges时,切屏会从新调用各个生命周期,默认首先销毁当前activity,而后从新加载
二、设置Activity的android:configChanges="orientation|keyboardHidden|screenSize"时,切屏不会从新调用各个生命周期,只会执行onConfigurationChanged方法,游戏开发中, 屏幕的朝向都是写死的.
如何将一个Activity设置成窗口的样式。
能够自定义一个activity的样式
android:theme="@android:style/Theme.Dialog"
你后台的Activity被系统 回收怎么办?若是后台的Activity因为某缘由被系统回收了,如何在被系统回收以前保存当前状态?
除了在栈顶的activity,其余的activity都有可能在内存不足的时候被系统回收,一个activity越处于栈底,被回收的可能性越大.若是有多个后台进程,在选择杀死的目标时,采用最近最少使用算法(LRU)。
Activity中提供了一个 onSaveInstanceState()回调方法,这个方法会保证必定在活动被回收以前调用, 能够经过这个方法来解决活动被回收时临时数据得不到保存的问题。onSaveInstanceState()方法会携带一个 Bundle类型的参数,Bundle提供了一系列的方法用于保存数据,好比可使用 putString()方法保存字符串,使用 putInt()方法保存整型数据。每一个保存方法须要传入两个参数,第一个参数是键,用于后面从 Bundle中取值,第二个参数是真正要保存的内容。在 MainActivity中添加以下代码就能够将临时数据进行保存:
protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); String tempData = "Something you just typed"; outState.putString("data_key", tempData); }
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState != null) { String tempData = savedInstanceState.getString("data_key"); }
也能够经过onRestoreInstanceState来存储和恢复数据,区别是不须要判断空了,onRestoreInstanceState调用必定是有值的
Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并非生命周期方法,它们不一样于 onCreate()、onPause()等生命周期方法,它们并不必定会被触发。当应用遇到意外状况(如:内存不足、用户直接按Home键)由系统销毁一个Activity,onSaveInstanceState() 会被调用。可是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。除非该activity是被用户主动销毁的,一般onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。
系统不知道你按下HOME后要运行多少其余的程序,天然也不知道activity A是否会被销毁,所以系统都会调用onSaveInstanceState(),让用户有机会保存某些非永久性的数据。如下几种状况的分析都遵循该原则
如何退出Activity?
退出activity 直接调用 finish () 方法
用户点击back键 就是退出一个activity ,退出activity 会执行 onDestroy()方法 。
一、抛异常强制退出:
该方法经过抛异常,使程序Force Close。不推荐使用
验证能够,可是,须要解决的问题是,如何使程序结束掉,而不弹出Force Close的窗口。
安全结束进程 android.os.Process.killProcess(android.os.Process.myPid());
二、记录打开的Activity:
每打开一个Activity,就用集合记录下来。在须要退出时,关闭每个Activity便可。
能够写在Application里,直接getApplication.list.add,在须要退出时遍历集合里的Activity,finish掉
也能够定义一个baseactivity里面进行操做,记得通常不用的话最后都须要把list=null
三、发送特定广播:
//在baseactivity里注册广播
registerReceiver(receiver, filter)
//想退出的时候就在onRecriver方法里finish()。
四、能够经过 intent的flag 来实现.. intent.setFlag(FLAG_ACTIVITY_CLEAR_TOP)激活一个新的activity,而后在新的activity的oncreate方法里面就能够finish掉.
讲一讲你对activity的理解
把上面的几点用本身的心得写出来
两个Activity之间怎么传递数据?
//把数据封装至intent对象中
startActivity(intent);
怎么让在启动一个Activity是就启动一个service?
在activity的onCreate()方法里面 startService();
如何返回数据
基本流程:
独的任务栈) ,不能被摧毁(执行不到 finish 方法) ,父 Activity 中的 onActivityResult 方法将不会执行;
请描述一下Intent 和 Intent Filter。
Android 中经过 Intent 对象来表示一条消息,一个 Intent 对象不只包含有这个消息的目的地,还能够包含消息的内容,这比如一封 Email,其中不只应该包含收件地址,还能够包含具体的内容。对于一个 Intent 对象,消息“目的地”是必须的,而内容则是可选项。
经过Intent 能够实现各类系统组件的调用与激活.
Intent filter:是传递的信息,这些信息不是必须的,有:
Action: 动做 view
Data: 数据uri uri
Category : 而外的附加信息
<intent-filter > <action android:name="com.itheima.second"/> <data android:scheme="asd" android:mimeType="aa/bb"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> Intent intent = new Intent("com.example.activitytest.ACTION_START");
PendingIntent和Intent区别
它们均可以去指明某一个“意图”,均可以用于启动活动、启动服务以及发送广播等。不一样的是,Intent更加倾向于去当即执行某个动做,而 PendingIntent更加倾向于在某个合适的时机去执行某个动做。因此,也能够把 PendingIntent简单地理解为延迟执行的 Intent。
PendingIntent的用法一样很简单,它主要提供了几个静态方法用于获取 PendingIntent的实例,能够根据需求来选择是使用 getActivity()方法、getBroadcast()方法、仍是 getService()方法。
每8小时开启广播
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE); int anHour = 8 * 60 * 60 * 1000; // 这是8小时的毫秒数 long triggerAtTime = SystemClock.elapsedRealtime() + anHour; Intent i = new Intent(this, AutoUpdateReceiver.class); PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0); manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
Intent传递数据和Bundle传递数据是一回事,
Intent传递时内部仍是调用了Bundle。
如下为源码:
public Intent putExtra(String name, boolean value) { if (mExtras == null) { mExtras = new Bundle(); } mExtras.putBoolean(name, value); return this; }
启动一个Activity有哪几种方法
startActivity
startActivityforresult
launcher的activity
widget
同一个程序,但不一样的Activity是否能够放在不一样的Task任务栈中?
启动模式里有个Singleinstance,能够运行在另外的单独的任务栈里面。用这个模式启动的activity,在内存中只有一份,这样就不会重复的开启。
也能够在激活一个新的activity时候, 给intent设置flag,Intent的flag添加FLAG_ACTIVITY_NEW_TASK,这个被激活的activity就会在新的task栈里面
Android中Task任务栈的分配。
1)任务栈的概念
问:一个手机里面有多少个任务栈?
答:通常状况下,有多少个应用正在运行,就对应开启多少个任务栈;每开启一个应用程序就会建立一个与之对应的任务栈;
栈:后进先出,最早进栈,就会最后出栈。Activity的启动模式就是修改任务栈的排列状况
2)任务栈的做用:
它是存放 Activity 的引用的,Activity不一样的启动模式,对应不一样的任务栈的存放;
可经过 getTaskId()来获取任务栈的 ID,若是前面的任务栈已经清空,新开的任务栈 ID+1,是自动增加的;
首先来看下Task的定义,Google是这样定义Task的:Task其实是一个Activity栈,一般用户感觉的一个Application就是一个Task。从这个定义来看,Task跟Service或者其余Components是没有任何联系的,它只是针对Activity而言的。
Activity的启动模式
Android下的进程
进程是被系统建立的,当内存不足的时候,又会被系统回收
内存管理:Android 系统在运行多个进程时,若是系统资源不足,会强制结束一些进程,优先选择哪一个进程来结束是有优先级的。
会按照如下顺序杀死(进程级别):
①、空: 进程中没有任何组件(无组件启动,作进程缓存使用,恢复速度快),任务栈清空,意味着程序退出了,但进程留着,这个就是空进程,容易被系统回收;
②、后台:进程中只有中止状态(onStop)的 Activity;
③、服务:进程中有正在运行的服务;
④、可见:进程中有一个暂停状态(onPause)的 Activity;
⑤、前台:进程中正在运行一个 Activity;
Activity 在退出的时候进程不会销毁, 会保留一个空进程方便之后启动. 但在内存不足时进程会被销毁;
Activity 中不要在 Activity 作耗时的操做, 由于 Activity 切换到后台以后(Activity 中止了), 内存不足时, 也容易被销毁;
Service
什么是Service以及描述下它的生命周期。Service有哪些启动方法,有什么区别,怎样停用Service?
在Service的生命周期中,被回调的方法比Activity少一些,只有onCreate, onStartCommand, onDestroy,onBind和onUnbind。
一般有两种方式启动一个Service,他们对Service生命周期的影响是不同的。
1 经过startService
Service会经历 onCreate 到onStartCommand,而后处于运行状态,stopService的时候调用onDestroy方法。
若是是调用者本身直接退出而没有调用stopService的话,Service会一直在后台运行。
2 经过bindService
Service会运行onCreate,而后是调用onBind, 这个时候调用者和Service绑定在一块儿。调用者退出了,Srevice就会调用onUnbind->onDestroyed方法。所谓绑定在一块儿就共存亡了。调用者也能够经过调用unbindService方法来中止服务,这时候Srevice就会调用onUnbind->onDestroyed方法。
3.当调用了startService()方法后,又去调用 stopService()方法,这时服务中的 onDestroy()方法就会执行,表示服务已经销毁了。相似地,当调用了 bindService()方法后,又去调用unbindService()方法,onDestroy()方法也会执行,这两种状况都很好理解。可是须要注意,咱们是彻底有可能对一个服务既调用了startService()方法,又调用了bindService()方法的,这种状况下该如何才能让服务销毁掉呢?根据Android系统的机制,一个服务只要被启动或者被绑定了以后,就会一直处于运行状态,必需要让以上两种条件同时不知足,服务才能被销毁。因此,这种状况下要同时调用stopService()和unbindService()方法,onDestroy()方法才会执行这样就把服务的生命周期完整地走了一遍。
start –> bind -> unbind -> stop 常用服务长期后台运行,又能够调用服务中的方法
service如何杀不死?
1.onStartCommand方法,返回START_STICKY(粘性)当service因内存不足被kill,当内存又有的时候,service又被从新建立
2.设置优先级,在服务里的ondestory里发送广播 在广播里再次开启这个服务,双进程守护
service是否在main thread中执行, service里面是否能执行耗时的操做?
默认状况,若是没有显示的指定service所运行的进程, Service和Activity是运行在当前app所在进程的main thread(UI主线程)里面
service里面不能执行耗时的操做(网络请求,拷贝数据库,大文件 ),须要在子线程中执行 new Thread(){}.start();
service里面能够弹土司吗
service里面弹toast须要添加到主线程里执行
@Override public void onCreate(){ handler = new Handler(Looper.getMainLooper()); System.out.println("service started"); handler.post(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), "Test",Toast.LENGTH_SHORT).show(); }); }
Activity怎么和service绑定,怎么在activity中启动本身对应的service?
startService() 一旦被建立 调用着无关,无法使用service里面的方法
bindService () 把service 与调用者绑定 ,若是调用者被销毁, service会销毁,可使用service 里面的方法
方法一:
方法二
经过BroadCast(广播)的形式
当咱们的进度发生变化的时候咱们发送一条广播,而后在Activity的注册广播接收器,接收到广播以后更新视图
什么是IntentService?有何优势?
普通的service ,默认运行在ui main 主线程,Sdk给咱们提供的方便的,带有异步处理的service类
OnHandleIntent() 处理耗时的操做,不须要开启子线程,这个方法已经在子线程中运行了
Intentservice若未执行完成上一次的任务,将不会新开一个线程,是等待以前的任务完成后,再执行新的任务,等任务完成后再次调用stopService()
startForeground(id, notification)
拥有service的进程具备较高的优先级。当内存不足时,拥有service的进程具备较高的优先级。
1. 若是service正在调用onCreate, onStartCommand或者onDestory方法,那么用于当前service的进程至关于前台进程以免被killed。
2. 若是当前service已经被启动(start),拥有它的进程则比那些用户可见的进程优先级低一些,可是比那些不可见的进程更重要,这就意味着service通常不会被killed.
3. 若是客户端已经链接到service (bindService),那么拥有Service的进程则拥有最高的优先级,能够认为service是可见的。
4. 若是service可使用startForeground(int, Notification)方法来将service设置为前台状态,那么系统就认为是对用户可见的,并不会在内存不足时killed。
何时使用Service?
若是有其余的应用组件做为Service,Activity等运行在相同的进程中,那么将会增长该进程的重要性。
1.Service的特色可让他在后台一直运行,能够在service里面建立线程去完成耗时的操做.
2.Broadcast receiver捕获到一个事件以后,能够起一个service来完成一个耗时的操做.
广播
请描述一下Broadcast Receiver。
Android中:系统在运行过程当中,会产生会多事件,那么某些事件产生时,好比:电量改变、收发短信、拨打电话、屏幕解锁、开机,系统会发送广播,只要应用程序接收到这条广播,就知道系统发生了相应的事件,从而执行相应的代码。使用广播接收者,就能够收听广播
广播分两种:有序广播、无序广播
无序广播:无序广播不可中断,不能互相传递数据;
有序广播:一个接一个的传递,广播可中断,经过调用 abortBroadcast()方法;接收者之间能够传递数据(intent);
无序广播(标准广播)
有序广播
<intent-filter android:priority="100" > <action android:name="com.example.broadcasttest.MY_BROADCAST"/> </intent-filter>
如何注册广播
public class MainActivity extends Activity { private IntentFilter intentFilter; private NetworkChangeReceiver networkChangeReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); intentFilter = new IntentFilter(); intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); networkChangeReceiver = new NetworkChangeReceiver(); registerReceiver(networkChangeReceiver, intentFilter); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(networkChangeReceiver); } class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "network changes",Toast.LENGTH_SHORT).show(); } } }
四大组件其中比较特殊的是广播接收者,能够不在清单文件中配置,能够经过代码进行注册。其余组件所有在清单文件中注册
Intent intent = new Intent("my-sensitive-event"); intent.putExtra("event", "this is a test event"); LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
广播的生命周期
a. 广播接收者的生命周期很是短暂的,在接收到广播的时候建立,onReceive()方法结束以后销毁;
b. 广播接收者中不要作一些耗时的工做,不然会弹出 Application No Response错误对话框;
c. 最好也不要在广播接收者中建立子线程作耗时的工做,由于广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉;
d. 耗时的较长的工做最好放在服务中完成;
内容提供者
请介绍下ContentProvider是如何实现数据共享的。
是四大组件之一,内容提供者的做用:把私有数据暴露给其余应用,一般,是把私有数据库的数据暴露给其余应用
在清单文件中定义内容提供者的标签,注意必需要有authorities属性,这是内容提供者的主机名,功能相似地址
<provider android:name="com.itheima.contentprovider.PersonProvider" android:authorities="com.itheima.person" android:exported="true" ></provider>
把本身的数据经过uri的形式共享出去,android 系统下不一样程序,数据默认是不能共享访问
须要去实现一个类去继承ContentProvider
为何要用ContentProvider?它和sql的实现上有什么差异?
屏蔽数据存储的细节,对用户透明,用户只须要关心操做数据的uri就能够了
不一样app之间共享,操做数据
Sql也有增删改查的方法.
可是contentprovider 还能够去增删改查本地文件. xml文件的读取,更改,网络数据读取更改
请介绍下Android的数据存储方式
1.文件储存,在内部文件和SD卡
getCacheDir(),在data/data/包名/cache
getFilesDir(),在data/data/包名/files
SD卡:首先通过File file = new File(Environment.getExternalStorageDirectory(), "info.txt"),而后经过io存储
2.SharedPreference
3.SQLite数据库:
当应用程序须要处理的数据量比较大时,为了更加合理地存储、管理、查询数据,每每使用关系数据库来存储数据。Android系统的不少用户数据,如联系人信息,通话记录,短信息等,都是存储在SQLite数据库当中的,因此利用操做SQLite数据库的API能够一样方便的访问和修改这些数据。
4.ContentProvider:
主要用于在不一样的应用程序之间实现数据共享的功能,不一样于sharepreference和文件存储中的两种全局可读写操做模式,内容提供其能够选择只对哪一部分数据进行共享,从而保证咱们程序中的隐私数据不会有泄漏的风险
Fragment
简单说说Fragment?
用途:在一个Activity里切换界面,切换界面时只切换Fragment里面的内容
生命周期方法跟Activity一致,能够理解把其为就是一个Activity,与Activity同存亡,Activity的XX方法调用,Fragment的XX方法就调用
他们是怎么进行传递数据的?
活动传递给Fragment:为了方便碎片和活动之间进行通讯, FragmentManager提供了一个相似于findViewById()的方法,专门用于从布局文件中获取碎片的实例,前提是本身在布局文件中定义fragment这个标签,代码以下所示:
RightFragment rightFragment = (RightFragment) getFragmentManager() .findFragmentById(R.id.right_fragment);
调用 FragmentManager的 findFragmentById()方法,能够在活动中获得相应碎片的实例,而后就能轻松地调用碎片里的方法了。还有findViewByTag,在replace 的时候设置tag
或者在fragment里声明接口,而后activity得到fragment对象调用接口里的方法
fragment数据传递给活动,直接getActivity就能够调用活动里的方法了
activity给fragment传递数据通常不经过fragment的构造方法来传递,会经过setArguments来传递,由于当横竖屏会调用fragment的空参构造函数,数据丢失。
fragment和fragment数据传递
首先在一个fragment能够获得与它相关联的活动,而后再经过这个活动去获取另一个fragment的实例,这样也就实现了不一样fragment之间的通讯功能
FragmentManager , add 和 replace 有什么区别?
Fragment和view的区别
Fragment能够有效的对 view进行管理(增删和替换)并且结构更加清晰,有模块化的实现思想。
用view 不少逻辑代码可能都须要写在Activity里,若是view不少, 耦合度会很高。用Fragment则能够各自管理,起了解耦的做用。
通常软件简单的话直接view,复杂的用Fragment。
viewpager是一个滑动切换的控件,Fragment是一个轻量级的Activity,这个Fragment能够放到这个Viewpager里面去运行。
例如QQ或微信那样,能够来回切换不一样的选项卡,即切换了不一样的Fragment。一般Viewpager 会放fargment或者view
Fragment和Activity的区别
由于如今的手机屏幕都比较大了,Activity会把内容拉的很长,用Fragment的话能够左侧是列表,右侧是内容。在一个Activity里切换界面,切换界面时只切换Fragment里面的内容。Fragment一般用来做为一个activity界面的一部分。
请介绍下Android中经常使用的五种布局。
FrameLayout(帧布局),LinearLayout (线性布局),AbsoluteLayout(绝对布局),RelativeLayout(相对布局),TableLayout(表格布局)
TextView 、ImageView ,Button,ImageButton他们之间的联系和区别
ImageView 控件负责显示图片,其图片来源既能够是资源文件的id,也能够是Drawable对象或 Bitmap 对象,还能够是 内容提供者(Content Provider)的Uri.
ImageButton 控件 继承自 ImageView。与Button相同之处:都用于响应按钮的点击事件
不一样之处:ImageButton只能显示图片;Button用于显示文字
屏幕适配
RelativeLayout和FrameLayout的区别
Padding和Margin有什么区别?
Padding 是控件内容的距离margin是控件和控件间的距离
Listview如何显示不一样条目?
第一种:在getview方法里根据position 进行判断,好比,position等于0是,显示标题,不然显示数据,固然相应的setOnItemClickListener也要去判断
第二种:根据listview里的getItemViewType,getViewTypeCount方法显示不一样条目
/** 根据位置 判断当前条目是什么类型 */ @Override public int getItemViewType(int position) { //20 if (position == datas.size()) { // 当前是最后一个条目 return MORE_ITEM; } return getInnerItemViewType(position); // 若是不是最后一个条目 返回默认类型 } private int getInnerItemViewType(int position) { return DEFAULT_ITEM; } /** 当前ListView 有几种不一样的条目类型 */ @Override public int getViewTypeCount() { return super.getViewTypeCount() + 1; // 2 有两种不一样的类型 }
ScrowView 使用的注意
在不一样的屏幕上显示内容不一样的状况,其实这个问题咱们每每是用滚动视图来解决的,也就是 ScrowView,
须要注意的是 ScrowView 中使用 layout_weight 是无效的,既然使用 ScrowView 了,就把它里面的控件的大小都设成固定的吧。
Android UI中的View如何刷新
在主线程中 拿到view调用Invalide()方法,在子线程里面能够经过postInvalide()方法;
invalidate();//主线程,刷新当前视图 致使 执行onDraw执行
postInvalidate();//子线程
什么是ANR(异步加载) 如何避免它?
android在主线程是不能加载网络数据或图片、数据库查询、复杂业务逻辑处理以及费时任务操做,由于Android的UI操做并非线程安全的,而且全部涉及UI的操做必须在UI线程中完成。Android应用在5s内无响应的话会致使ANR(Application Not Response),这就要求开发者必须遵循两条法则:一、不能阻塞UI线程,二、确保只在UI线程中访问Android UI工具包。
Activity 5秒 broadcast10秒,服务20秒,耗时的操做在主thread里面完成
解决办法:Thread + Handler + Message ,Thread + Handler + post,AsyncTask,intentservice
runOnUiThread(Runnable)在子线程中直接使用该方法,能够更新UI
实现侧边栏、和指示器效果、页面滑动有几种方式
侧边栏:自定义、slidingmenu、DrawerLayout 、SlidingDrawer
指示器效果:自定义、viewpager里面的PagerTabStrip、ActionBar Tab标签、viewpagerindicate、FragmentTabHost、TabActivity、radiobutton
页面滑动:自定义、viewpager、手势识别器,其实就是onTouchEvent提供的简单工具类,onTouchEvent将触摸事件委托给了手势识别器
Gradle中buildToolsVersion和TargetSdkVersion的区别是什么
compileSdkVersion, minSdkVersion 和 targetSdkVersion 的做用:他们分别控制可使用哪些 API ,要求的 API 级别是什么,以及应用的兼容模式。TargetSdkVersion 设为23那么是按6.0设置的(运行时权限),小于23是按6.0之前的方式(安装时默认得到权限,且用户没法在安装App以后取消权限)
进程间怎么通讯
binder是安卓中的一个类,它实现了IBinder接口,是安卓中跨进程通讯的方式。当绑定服务的时候会返回一个binder对象,而后经过他进行多进程间的通讯。
其实进程间通讯就是为了实现数据共享。一个程序不一样组件在不一样进程也叫多进程,和俩个应用没有本质区别。使用process属性能够实现多进程,可是会带来不少麻烦,主要缘由是共享数据会失败,弊端有:静态和单利失效,同步失效,sharedprefer可靠性减低等问题
Intent,Binder(AIDL),sharedpre、Messenger
使用多进程显而易见的好处就是分担主进程的内存压力。咱们的应用越作越大,内存愈来愈多,将一些独立的组件放到不一样的进程,它就不占用主进程的内存空间了。固然还有其余好处,有心人会发现Android后台进程里有不少应用是多个进程的,由于它们要常驻后台,特别是即时通信或者社交应用,不过如今多进程已经被用烂了。典型用法是在启动一个不可见的轻量级私有进程,在后台收发消息,或者作一些耗时的事情,或者开机启动这个进程,而后作监听等。还有就是防止主进程被杀守护进程,守护进程和主进程之间相互监视,有一方被杀就从新启动它。
假设手机本地须要缓存数据,如何保证和服务器的数据统一?
好比有个网络更新的功能,activity能够每隔半小时开启service去访问服务器,获取最新的数据。
在缓存文件里面加入时间戳,根据实际状况在必定的时间差内再次访问网络数据、判断URL
在缓存的第一行写一个上当前时间,读的时候判断是否是过时,根据需求看须要多久跟新
分页怎么作的?
分页根据服务器接口参数决定每次加载多少,getviewtype,getitemview
分批处理 解决的是时间等待的问题,不能解决内存占用的问题。
要想解决内存占用问题,能够采用分页方式
什么Context
Android工程环境中像Activity、Service、BroadcastReceiver等系统组件,而这些组件并非像一个普通的Java对象new一下就能建立实例的了,而是要有它们各自的上下文环境,这就是Context。能够这样讲,Context是维持Android程序中各组件可以正常工做的一个核心功能类。
Context功能不少,能够弹出Toast、启动Activity、启动Service、发送广播、操做数据库等等等等都须要用到Context。
Context一共有Application、Activity和Service三种类型:Context数量 = Activity数量 + Service数量 + 1 。1表明着Application的数量,由于一个应用程序中能够有多个Activity和多个Service,可是只能有一个Application。
Android程序与Java程序的区别?
Android程序用android sdk开发,java程序用javasdk开发.
Android SDK引用了大部分的Java SDK,少数部分被Android SDK抛弃,好比说界面部分,java.awt swing package除了java.awt.font被引用外,其余都被抛弃,在Android平台开发中不能使用。 Android sdk 添加工具jar httpclient , pull opengl
Android中的动画有哪几类,它们的特色和区别是什么?
属性动画:动画的对象除了传统的View对象,还能够是Object对象,动画结束后,Object对象的属性值被实实在在的改变了
Android工程的目录结构
src:项目的java代码
assets:资源文件夹,存放视频或者音乐等较大的资源文件
bin:存放应用打包编译后的文件
res:资源文件夹,在这个文件夹中的全部资源,都会有资源id,读取时经过资源id就能够读取
资源id不能出现中文
coverview原理:
这个参数用于将以前加载好的布局进行缓存,以便以后能够进行重用,在 getView()方法中进行了判断,若是 convertView为空,则使用
LayoutInflater去加载布局,若是不为空则直接对 convertView进行重用
android的启动流程
当程序启动Linux内核后,会加载各类驱动和数据结构,当有了驱动之后,开始启动Android系统同时会加载用户级别的第一个进程init(system\core\init.c),加载init.rc文件,会启动一个Zygote进程,此进程是Android系统的一个母进程,用来启动Android的其余服务进程,而后接着在里面启动各类硬件服务和activity。Android系统启动完成,打开了Luncher应用的Home界面。
Logcat
1. Log.v()
这个方法用于打印那些最为琐碎的,意义最小的日志信息。对应级别 verbose,是Android日志里面级别最低的一种。
2. Log.d()
这个方法用于打印一些调试信息, 这些信息对你调试程序和分析问题应该是有帮助的。对应级别 debug,比 verbose高一级。
3. Log.i()
这个方法用于打印一些比较重要的数据,这些数据应该是你很是想看到的,能够帮你分析用户行为的那种。对应级别 info,比 debug高一级。
4. Log.w()
这个方法用于打印一些警告信息,提示程序在这个地方可能会有潜在的风险,最好去修复一下这些出现警告的地方。对应级别 warn,比 info高一级。
5. Log.e()
这个方法用于打印程序中的错误信息,好比程序进入到了 catch语句当中。当有错误信息打印出来的时候,通常都表明你的程序出现严重问题了,必须尽快修复。对应级别 error,比 warn高一级.
推送
全部须要客户端被动接收信息的功能模块,均可以用推送实现,好比A想给B发消息,A调服务器接口,服务器只是存数据,它调推送的接口,推送去去找B。推送用的是xmpp协议, 是一种基于TCP/IP的协议, 这种协议更适合消息发送
- socket 套接字, 发送和接收网络请求
- 长链接 keep-alive, 服务器基于长链接找到设备,发送消息
- 心跳包 , 客户端会定时(30秒一次)向服务器发送一段极短的数据,做为心跳包, 服务器定时收到心跳,证实客户端或者,才会发消息.不然将消息保存起来,等客户端活了以后(从新链接),从新发送.
因为篇幅缘由,附俩篇优化和自定义控件常见的面试题,但愿对你们有所帮助: