Android中四大组件以及如何避免anr
来源:互联网 发布:管家婆软件普普版 编辑:程序博客网 时间:2024/06/05 13:01
一个Android程序有四大基本组件,但只有activity是必须有的
1,activity:可视化的交互界面, 为一个Android程序添加一个activity的步骤是
第一步:新建一个类继承自activity, 并且为该activity设置布局文件
<span style="font-size:14px;">public class MyNext extends Activity { ...... setContentView(R.layout.activity_next); }</span>
第二步,在Androidmanifest.xml清单文件中配置该activity
<span style="font-size:14px;"> <activity android:name=".activity.MyNext"/></span></span>
至此,一个新的activity就添加成功了,一个activity的生命周期为:onCreate,onStart,onResume,onPause,onStop,onDestroy
2,service:服务,无界面,生命周期长,不可见,可运行在后台的组件,为一个Android程序添加服务的步骤是
第一步:新建一个类继承自Service
<span style="font-size:14px;"> public class MyService extends Service { ...... }</span>
第二步,在Androidmanifest.xml清单文件中进行配置该service
<span style="font-size:14px;"> <service android:name=".MyService"/></span>
第三步,在activity中开启服务
开启服务的方式 有两种
第一种: 利用startService开启的服务与 访问者相互独立,必须调用stopService 来结束服务
<span style="font-size:14px;"> //开启服务 startService(new Intent(MyNext.this,MyService.class)); //结束服务 stopService(new Intent(MyNext.this,MyService.class));</span>
利用 这种方式开启服务时其生命周期为:onCreate-->onStartCommand--->onDestroy,当我多次调用startService时,如果服务已经被创建则只会调用onStartCommand方法,若未创建则去调用onCreate。。。。
<span style="font-size:14px;">12-16 11:09:38.154 21909-21909/com.example.yong.myfirstdemo I/tag﹕ 调用的方法是->>onCreate---com.example.yong.myfirstdemo.MyService12-16 11:09:38.154 21909-21909/com.example.yong.myfirstdemo I/tag﹕ 调用的方法是->>onStartCommand---com.example.yong.myfirstdemo.MyService12-16 11:09:40.599 21909-21909/com.example.yong.myfirstdemo I/tag﹕ 调用的方法是->>onStartCommand---com.example.yong.myfirstdemo.MyService12-16 11:09:40.898 21909-21909/com.example.yong.myfirstdemo I/tag﹕ 调用的方法是->>onStartCommand---com.example.yong.myfirstdemo.MyService12-16 11:09:43.090 21909-21909/com.example.yong.myfirstdemo I/tag﹕ 调用的方法是->>onyDestroy---com.example.yong.myfirstdemo.MyService</span>
第二种: 利用bindService开启服务,该服务依赖于访问者而存在, 若访问者退出则服务结束,所以如果要求服务和访问者 同时结束,不需要调用任何方法去结束服务。如果想要在访问者未 结束时就结束服务,需要调用unbindService方法。
<span style="font-size:14px;"> //开启服务 bindService(new Intent(MyNext.this,MyService.class), serviceConnection, BIND_AUTO_CREATE); //关闭服务,参数与开启服务中的serviceConnection为同一个,若不相同,会出现如下错误 unbindService(serviceConnection);</span>
当bindservice方法与unbindService方法的参数serviceConnection使用的不同时会出现如下错误,如果出现如下I错去,那就要检查一下serviceConnection是不是在unbindService时重新创建了一次:
<span style="font-size:14px;">java.lang.IllegalArgumentException: Service not registered: com.example.yong.myfirstdemo.activity.MyNext$MyServiceConn@411c3870 at android.app.LoadedApk.forgetServiceDispatcher(LoadedApk.java:959) at android.app.ContextImpl.unbindService(ContextImpl.java:1574) at android.content.ContextWrapper.unbindService(ContextWrapper.java:484) at com.example.yong.myfirstdemo.activity.MyNext.onClick(MyNext.java:191) at android.view.View.performClick(View.java:4222) at android.view.View$PerformClick.run(View.java:17624) at android.os.Handler.handleCallback(Handler.java:800) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:194) at android.app.ActivityThread.main(ActivityThread.java:5398) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:525) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:836) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:603) at dalvik.system.NativeStart.main(Native Method)</span>用这种方式开启服务时服务的生命周期为:onCreate-->onBind-->onUnbind-->onDestroy,在服务创建后,我调用多次bindService方法,不会再去调用onCreate 和onBind方法。。在服务创建后不论是退出activity还是调用unbindService方法都会去调用onUnbind和onDestroy方法
<span style="font-size:14px;">12-16 11:12:57.410 22870-22870/com.example.yong.myfirstdemo I/tag﹕ 调用的方法是->>onCreate---com.example.yong.myfirstdemo.MyService12-16 11:12:57.411 22870-22870/com.example.yong.myfirstdemo I/tag﹕ 调用的方法是->>onBind---com.example.yong.myfirstdemo.MyService12-16 11:13:06.918 22870-22870/com.example.yong.myfirstdemo I/tag﹕ 调用的方法是->>onUnbind---com.example.yong.myfirstdemo.MyService12-16 11:13:06.922 22870-22870/com.example.yong.myfirstdemo I/tag﹕ 调用的方法是->>onyDestroy---com.example.yong.myfirstdemo.MyService</span>
但是如果未调用bindService方法,就 调用unbindService方法,则会出现以下异常:
<span style="font-size:14px;">java.lang.IllegalArgumentException: Service not registered: com.example.yong.myfirstdemo.activity.MyNext$MyServiceConn@412019c0 at android.app.LoadedApk.forgetServiceDispatcher(LoadedApk.java:959) at android.app.ContextImpl.unbindService(ContextImpl.java:1574) at android.content.ContextWrapper.unbindService(ContextWrapper.java:484) at com.example.yong.myfirstdemo.activity.MyNext.onClick(MyNext.java:186) at android.view.View.performClick(View.java:4222) at android.view.View$PerformClick.run(View.java:17624) at android.os.Handler.handleCallback(Handler.java:800) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:194) at android.app.ActivityThread.main(ActivityThread.java:5398) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:525) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:836) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:603) at dalvik.system.NativeStart.main(Native Method)</span>
如果出现上述异常,仅仅是因为未绑定服务,可以用try/catch语句来提醒用户还未绑定服务
<span style="font-size:14px;"> try { unbindService(serviceConnection); } catch (IllegalArgumentException e) { //异常处理代码 Log.i("tag","还未绑定服务"); }</span>
3,BroadcastReceiver,广播接收器,广播接收器只有一个方法onReceive,广播接收器组件用法如下:
第一步:自定义一个类,继承自BroadcastReceiver,并重写onReceive方法,代码如下:
<span style="font-size:14px;"> class MyBroadCastReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { //监听到广播时的代码 Log.i("tag", "调用的方法是->>onReceive" + "---" + getClass().getName()); } }</span>
第二步,注册广播,和服务类似,广播的注册有两种形式,
第一种,在Androidmanifest.xml文件中注册
<span style="font-size:14px;"> <receiver android:name=".MyBroadCastReceiver"> <intent-filter> <action android:name="com.receiver"/> </intent-filter> </receiver></span>
第二种方式,在代码中注册,
<span style="font-size:14px;"> IntentFilter filter = new IntentFilter("com.receiver"); MyBroadCastReceiver mBroadCastReceiver = new MyBroadCastReceiver();</span>
<span style="font-size:14px;"> //注册广播 registerReceiver(mBroadCastReceiver, filter); //撤销广播 unregisterReceiver(mBroadCastReceiver);</span>
广播注册成功后,我们可以发送广播
<span style="font-size:14px;"> //发送广播 sendBroadcast(new Intent("com.receiver"));</span>
正如Service中bindService与unbindService必须成对出现,广播中registerReceiver与unregisterReceiver也必须成对出现,如果出现以下错误:
<span style="font-size:14px;"> java.lang.IllegalArgumentException: Receiver not registered: com.example.yong.myfirstdemo.MyBroadCastReceiver@411d37f8 at android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java:665) at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:1462) at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:445) at com.example.yong.myfirstdemo.activity.MyNext.onClick(MyNext.java:202) at android.view.View.performClick(View.java:4222) at android.view.View$PerformClick.run(View.java:17624) at android.os.Handler.handleCallback(Handler.java:800) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:194) at android.app.ActivityThread.main(ActivityThread.java:5398) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:525) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:836) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:603) at dalvik.system.NativeStart.main(Native Method)</span>
可以从两个方向去考虑,第一,在调用unregisterReceiver之前是否没有调用registerReceiver方法,第二,两个方法中的参数是否为同一个。。。如果是第一种情况,可以向处理service出现异常时的解决方案一样,在调用unregisterReceiver方法时进行try/catch,
try { unregisterReceiver(mBroadCastReceiver); }catch (IllegalArgumentException e){ //广播未注册时的处理代码 }
注册广播有两种方式,各有利弊
1,在xml中注册,属于常驻型广播,广播在应用开启前注册,在应用结束后,仍旧存在,不随着activity的结束而终止
2,在代码中注册,属于非常驻型,存活周期受activity影响,方便管理
总结:
面试必备的一个问题:如何去避免anr?anr是说程序无响应,是由于耗时操作造成 的,那么如何更好的避免呢?
首先,哪些属于耗时操作? 网络操作,大文件的拷贝,阻塞式的请求等属于耗时操作。。
activity属于可视化的用户交互界面,在activity的UI线程中执行耗时操作,或造成卡顿现象,直接影响用户体验,可以在activity中开启线程去进行耗时操作, 用AsyncTask解决。
广播接收器的onReceive方法执行时间特别短只有不到10s,这也就意味着无法在广播接收器中进行耗时操作,而且因为onReceive方法时间太短也无法去开启子线程来进行耗时操作,所以可以在onReceive方法中开启服务,在服务中进行耗时操作。
4,ContentProvider,内容提供者,两个程序之间共享私有数据
- Android中四大组件以及如何避免anr
- Android ANR 以及如何避免
- Android中如何避免ANR
- Android中ANR造成的原因以及如何避免
- 如何避免android ANR
- Android ANR是什么?如何避免ANR
- Android应用中如何避免出现ANR(Application NotResponding)
- 如何避免Android程序的ANR
- Android ANR定义及如何避免
- Android—什么是ANR 如何避免它?
- android什么是ANR,如何定位和避免
- 什么是ANR,如何避免ANR
- 什么是ANR?如何避免ANR?
- Android中四大组件
- Android中四大组件
- Android中四大组件
- Android中四大组件
- Android中四大组件
- SVN:适用地方和简介
- Day5之操作运算符2
- Your build settings specify a provisioning profile with the UUID “”, however, no such provisioning p
- sublime安装SVN插件的方法
- 记录安卓遇到的两个小bug,望初学者写代码的时候引以为戒
- Android中四大组件以及如何避免anr
- LS,MMSE,LMMSE,ML,MAP,LMS,AR,MSE误差介绍
- Day5之逻辑运算符
- samba 服务器
- CentOS7修改主机名
- MyBATIS原理第三篇: SqlSession下的四大对象之一——执行器(executor)
- MySql错误处理(四)- 错误代码和消息
- Day5之PropertyDemo
- mysql字段