您的位置:首页 > 移动开发 > Android开发

读书笔记|《第一行代码android》之组件篇

2016-07-08 08:50 531 查看
和朋友讨论说面对众多的计算机知识点学了为什么容易忘记。很多原因,包括缺少有方法的总结。我做了第一行有关广播接收器的总结后,发现记知识点的思路清晰了。慢慢做了其他组件的总结,算是一次查漏补缺,今后慢慢养成这个好习惯,定能收益匪浅。文章不尽详细,欢迎交流学习。

一、广播接收器(Broadcast Receiver)

1.使用动态注册:

1.都说要注册嘛,我首先记住注册的方法是registerReceiver()方法。(中文是注册接收器,好记!)这个方法第一个参数是自己定义的广播接收器类的对象,第二个是IntentFilter的对象。意思是将广播接收器接收IntentFilter发出的动作。故代码中需要定义这两个类对象和IntentFilter的动作addAction()。

2.然后少不了定义自己的广播接收器类,主要实现的是OnReceive()方法。

3.最后动态注册的广播接收器一定都要取消注册才行,用unregisterReceiver();

4.如果程序需要访问一些系统的关键信息,注意声明权限。

实例:监听网络变化

public class MainActivity extends Activity {
private IntentFilter intentFilter;
private NetworkChangeReceiver networkChangeReceiver;

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);
}

protected void onDestroy() {
super.onDestroy();
unregisterReceiver(networkChangeReceiver);
}
class NetworkChangeReceiver extends BroadcastReceiver {

public void onReceive(Context context, Intent intent) {

Toast.makeText(context, "network changes",Toast.LENGTH_SHORT).show();

}
}
}


2.使用静态注册:

<receiver android:name=".BootCompleteReceiver" >//广播接收器的名字
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />//接收的广播
</intent-filter>
</receiver>


仔细观察发现,静态注册就是将动态注册的内容换个形式搬到了AndroidManifest.xml 中,这样对比起来就容易记多了。

3.发送自定义广播代码

上面的监听网络变化可以理解是别处发出的广播,如果自己定义发出一条广播,这可以这样写,括号里面的内容自己定义,

Intent intent = new Intent("com.example.broadcasttest.MY_BROADCAST");
sendBroadcast(intent);


广播接收器注册了就能收听到了。

4.发送有序广播关键代码

sendOrderedBroadcast(intent, null);//改变发送广播的方法
android:priority="100"//定义广播接收器的优先级


5.本地广播关键代码

localBroadcastManager = LocalBroadcastManager.getInstance(this);// 获取实例
localBroadcastManager.sendBroadcast(intent); // 发送本地广播
localBroadcastManager.registerReceiver(localReceiver, intentFilter);// 注册本地广播监听器


6.广播接收器容易忽略的点

不要在 onReceive()方法中添加过多的逻辑或者进行任何的耗时操作,因为在广播接收器中是不允许开启线程的, 当 onReceive()方法运行了较长时间而没有结束时, 程序就会报错。因此广播接收器更多的是扮演一种打开程序其他组件的角色,比如创建一条状态栏通知,或者启动一个服务等。

强制用户下线的逻辑并不是写在 MainActivity 里的,而是应该写在接收这条广播的广播接收器里面,这样强制下线的功能就不会依附于任何的界面,不管是在程序的任何地方,只需要发出这样一条广播,就可以完成强制下线的操作了。

在广播接收器里启动活动的,因此一定要给Intent 加入 FLAG_ACTIVITY_NEW_TASK 这个标志。最后,还需要把对话框的类型设为TYPE_SYSTEM_ALERT,不然它将无法在广播接收器里弹出。

二、服务(Service)

1.服务常用的方法

onCreate()、onStartCommand()和 onDestroy()这三个方法,它们是每个服务中最常用到的三个方法了。其中 onCreate()方法会在服务创建的时候调用,onStartCommand()方法会在每次服务启动的时候调用,onDestroy()方法会在服务销毁的时候调用。通常情况下,如果我们希望服务一旦启动就立刻去执行某个动作,就可以将逻辑写在onStartCommand()方法里。而当服务销毁时,我们又应该在 onDestroy()方法中去回收那些不再使用的资源。其实 onCreate()方法是在服务第一次创建的时候调用的,而 onStartCommand()方法则在每次启动服务的时候都会调用。

2.活动与服务的通信(重点)

1.定义类继承Binder,在onBinder(Intent intent)方法中返回该类的实例;

2.在活动中重写onServiceConnected(ComponentName name, IBinder service),此处的参数service是onBind(Intent intent)方法返回的IBinder对象;

3.绑定bindService(Intent service,ServiceConnection conn,int flags)和unbindService()方法。

3.服务的生命周期

一旦在项目的任何位置调用了 Context 的 startService()方法,相应的服务就会启动起来, 并回调 onStartCommand()方法。如果这个服务之前还没有创建过,onCreate()方法会先于 onStartCommand()方法执行。服务启动了之后会一直保持运行状态,直到 stopService()或 stopSelf()方法被调用。注意虽然每调用一次 startService()方法,onStartCommand()就会执行 一次,但实际上每个服务都只会存在一个实例。所以不管你调用了多少次 startService()方法, 只需调用一次 stopService()或 stopSelf()方法,服务就会停止下来了。

另外,还可以调用 Context 的 bindService()来获取一个服务的持久连接,这时就会回调服务中的onBind()方法。类似地,如果这个服务之前还没有创建过,onCreate()方法会先于 onBind()方法执行。之后,调用方可以获取到 onBind()方法里返回的 IBinder 对象的实例,这 样就能自由地和服务进行通信了。只要调用方和服务之间的连接没有断开,服务就会一直保 持运行状态。

调用了 startService()方法后,又去调用 stopService()方法,这时服务中的 onDestroy() 方法就会执行,表示服务已经销毁了。类似地,当调用了 bindService()方法后,又去调用 unbindService()方法,onDestroy()方法也会执行,这两种情况都很好理解。但是需要注意, 我们是完全有可能对一个服务既调用了 startService()方法,又调用了 bindService()方法的, 这种情况下该如何才能让服务销毁掉呢?根据 Android 系统的机制,一个服务只要被启动或 者被绑定了之后,就会一直处于运行状态,必须要让以上两种条件同时不满足,服务才能被 销毁。所以,这种情况下要同时调用 stopService()和 unbindService()方法,onDestroy()方法才会执行。

三、内容提供器(Content Provider)

每一个应用程序来说,如果想要访问内容提供器中共享的数据,就一定要借助ContentResolve 类,可以通过 Context 中的 getContentResolver()方法获取到该类的实例。ContentResolver 中提供了一系列的方法用于对数据进行 CRUD 操作。

ContentResolver 中的增删改查方法都是不接收表名参数的,而是使用一个 Uri 参数代替,这个参数被称为内容 URI。内容 URI 给内容提供器中的数据建立了唯一标识符,它主要由两部分组成,权限(authority)和路径(path) 。

ContentResolver 中的增删改查方法
//查询
Cursor cursor = getContentResolver().query(
uri,
projection,
selection,
selectionArgs,
sortOrder);
//增加
ContentValues values = new ContentValues();
values.put("column1", "text");
values.put("column2", 1);
getContentResolver().insert(uri, values);
//更新
ContentValues values = new ContentValues();
values.put("column1", "");
getContentResolver().update(uri, values, "column1 = ? and column2 = ?", newString[] {"text", "1"});
//删除
getContentResolver().delete(uri, "column2 = ?", new String[] { "1" });
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息