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

来源:互联网 发布:ledrom编辑软件 编辑:程序博客网 时间:2024/05/01 10:10

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

广播接收器(Broadcast Receiver)

使用动态注册:

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

使用静态注册:

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

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

发送自定义广播代码

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

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

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

发送有序广播关键代码

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

本地广播关键代码

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

广播接收器容易忽略的点

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

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

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

服务(Service)

服务常用的方法

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

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

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()方法。

服务的生命周期

一旦在项目的任何位置调用了 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" });
0 0
原创粉丝点击