1.activity
生命周期如图
2.service
生命周期如图
service和thread的区别:
1.服务不是单一的进程。服务没有自己的进程,应用程序可以不同,服务运行在相同的进程中。
2.服务不是线程。可以在线程中工作。
一.在应用中,如果是长时间的在后台运行,而且不需要交互的情况下,使用服务。
同样是在后台运行,不需要交互的情况下,如果只是完成某个任务,之后就不需要运行,而且可能是多个任务,需需要长时间运行的情况下使用线程。
二.如果任务占用CPU时间多,资源大的情况下,要使用线程。
servie是系统的组件,它由系统进程托管(servicemanager);它们之间的通信类似于client和server,是一种轻量级的ipc通信,这种通信的载体是binder,它是在linux层交换信息的一种ipc。而thread是由本应用程序托管。
1). Thread:Thread 是程序执行的最小单元,它是分配CPU的基本单位。可以用 Thread 来执行一些异步的操作。
2). Service:Service 是android的一种机制,当它运行的时候如果是Local Service,那么对应的Service 是运行在主进程的 main 线程上的。如:onCreate,onStart 这些函数在被系统调用的时候都是在主进程的 main 线程上运行的。如果是Remote Service,那么对应的 Service 则是运行在独立进程的 main 线程上。
既然这样,那么我们为什么要用 Service 呢?其实这跟 android 的系统机制有关,我们先拿Thread 来说。Thread 的运行是独立于 Activity 的,也就是说当一个 Activity 被 finish 之后,如果你没有主动停止 Thread 或者 Thread 里的 run 方法没有执行完毕的话,Thread 也会一直执行。因此这里会出现一个问题:当 Activity 被 finish 之后,你不再持有该 Thread 的引用。另一方面,你没有办法在不同的 Activity 中对同一 Thread 进行控制。
举个例子:如果你的 Thread 需要不停地隔一段时间就要连接服务器做某种同步的话,该 Thread 需要在 Activity 没有start的时候也在运行。这个时候当你 start 一个 Activity 就没有办法在该 Activity 里面控制之前创建的 Thread。因此你便需要创建并启动一个 Service ,在 Service 里面创建、运行并控制该 Thread,这样便解决了该问题(因为任何 Activity 都可以控制同一 Service,而系统也只会创建一个对应 Service 的实例)。
因此你可以把 Service 想象成一种消息服务,而你可以在任何有 Context 的地方调用Context.startService、Context.stopService、Context.bindService,Context.unbindService,来控制它,你也可以在 Service 里注册 BroadcastReceiver,在其他地方通过发送 broadcast 来控制它,当然这些都是 Thread 做不到的。
作用:进程间通信,service来播放音乐,或者记录地理信息位置的改变,
或者启动一个服务来运行并一直监听某种动作,或者做下载。
startService
优点:使用简单,和Activity一样,只要几行代码即可启动Service
缺点:使用startService无法获得Service对象,不能直接操作Service中的属性和方法,只能通过Intent传递不同参数,
重复调用startService,触发onStartCommand
bindService
优点:可以得到Service对象,灵活控制Service内部的属性和方法
缺点:使用较为复杂
startService使用:
----------------------------------------------------------------
public class MyService extends Service {
public MyService()
{
}
@Override
public void onCreate(){
super.onCreate();
Log.v("MSoncreate","this is msoncreate");
}
@Override
public int onStartCommand(Intent intent,int flags,int startld){
Log.v("MSonstartcommand","this is MSonstartcommand");
return super.onStartCommand(intent,flags,startld);
}
public void onDestroy(){
super.onDestroy();
Log.v("MSondestry","this is MSondestroy");
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
------------------------------------------------------------
Activity:
-----------------------------------------------------------
mainB=(Button)findViewById(R.id.mainB);
mainStopB=(Button)findViewById(R.id.mainStopB);
mainB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent startintent=new Intent(getApplicationContext(),MyService.class);
startService(startintent);
}
});
mainStopB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent stopintent=new Intent(getApplicationContext(),MyService.class);
stopService(stopintent);
}
});
---------------------------------------------------------------------
bindService使用:
--------------------------------------------------------------------------
public class My2Service extends Service {
private MyBinder binder=new MyBinder();
private final Random generator = new Random();
public My2Service() {
}
public class MyBinder extends Binder
{
public My2Service getService(){
return My2Service.this;
}
}
@Override
public IBinder onBind(Intent intent) {
// // TODO: Return the communication channel to the service.
// throw new UnsupportedOperationException("Not yet implemented");
Log.v("MS2onbind","this is ms2onbind");
return binder;
}
@Override
public void onCreate(){
super.onCreate();
Log.v("MS2oncreate","this is ms2oncreate");
}
@Override
public int onStartCommand(Intent intent,int flags,int startld) {
Log.v("MS2onstartcommand", "this is ms2onstartcommand");
return super.onStartCommand(intent, flags, startld);
}
@Override
public void onRebind(Intent intent){
Log.v("MS2onrebind","ms2onrebind");
super.onRebind(intent);
}
@Override
public boolean onUnbind(Intent intent){
Log.v("MS2onunbind","this is onunbind");
return super.onUnbind(intent);
}
@Override
public void onDestroy(){
Log.v("MS2ondstroy","this is ms2ondestroy");
super.onDestroy();
}
//getRandomNumber是Service暴露出去供client调用的公共方法
public int getRandomNumber(){
return generator.nextInt();
}
}
-------------------------------------------------------------
Activity:
------------------------------------------------------------
private boolean isBound = false;
private My2Service service=null;
private ServiceConnection sc=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
isBound = true;
My2Service.MyBinder myBinder=(My2Service.MyBinder)iBinder;
service=myBinder.getService();
int num = service.getRandomNumber();
Log.v("MS2","this is sccted"+num+isBound);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.v("MS2","this is scdiscted"+isBound);
}
};
***************oncreate中************************
mainB=(Button)findViewById(R.id.mainB);
mainStopB=(Button)findViewById(R.id.mainStopB);
mainB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent bindintent=new Intent(getApplicationContext(),My2Service.class);
bindService(bindintent,sc,BIND_AUTO_CREATE);
Log.v("MS2","this is bind");
}
});
mainStopB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (isBound)
{
unbindService(sc);
isBound = false;
Log.v("MS2","this is unbind");
}else
{
Log.v("MS2","null");
}
}
});
-------------------------------------------------------------
3.BroadcastRecever
作用:Android不同组件间的通信(含 :应用内 / 不同应用之间)
多线程通信
与 Android 系统在特定情况下的通信
广播分类:
标准广播(Normal broadcasts):
完全异步执行的广播,接收没有先后顺序,效率高,无法被接收器被拦截。(动态优先级永远大于静态)
有序广播(Ordered broadcasts) : sendorderedBroadCast()
同步执行的广播,有先后顺序,广播可以被接收器拦截或修改。(动态静态按优先级排序)
广播的具体action:
监听网络变化 android.net.conn.CONNECTIVITY_CHANGE
关闭或打开飞行模式 Intent.ACTION_AIRPLANE_MODE_CHANGED
充电时或电量发生变化 Intent.ACTION_BATTERY_CHANGED
电池电量低 Intent.ACTION_BATTERY_LOW
电池电量充足(即从电量低变化到饱满时会发出广播 Intent.ACTION_BATTERY_OKAY
系统启动完成后(仅广播一次) Intent.ACTION_BOOT_COMPLETED
按下照相时的拍照按键(硬件按键)时 Intent.ACTION_CAMERA_BUTTON
屏幕锁屏 Intent.ACTION_CLOSE_SYSTEM_DIALOGS
设备当前设置被改变时(界面语言、设备方向等) Intent.ACTION_CONFIGURATION_CHANGED
插入耳机时 Intent.ACTION_HEADSET_PLUG
未正确移除SD卡但已取出来时(正确移除方法:设置--SD卡和设备内存--卸载SD卡) Intent.ACTION_MEDIA_BAD_REMOVAL
插入外部储存装置(如SD卡) Intent.ACTION_MEDIA_CHECKING
成功安装APK Intent.ACTION_PACKAGE_ADDED
成功删除APK Intent.ACTION_PACKAGE_REMOVED
重启设备 Intent.ACTION_REBOOT
屏幕被关闭 Intent.ACTION_SCREEN_OFF
屏幕被打开 Intent.ACTION_SCREEN_ON
关闭系统时 Intent.ACTION_SHUTDOWN
重启设备 Intent.ACTION_REBOOT
静态注册:(手动配置xml)
------------xml-------------------------------------
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.bn.mytest.JTZC"/>
</intent-filter>
</receiver>
---------AndroidStudio生成broadcast----------
---------activity-----------------------------------
mainB=(Button)findViewById(R.id.mainB);
mainB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.v(tag,"this is JTReceverOnrecever");
Intent intent=new Intent();
intent.setAction("com.bn.mytest.JTZC");
intent.putExtra("info","this is fromJTZC");
sendBroadcast(intent);
}
});
---------------------------------------------------------
动态注册:
---------------activity-------------------------
DTBroadcast dtBroadcast=null;
class DTBroadcast extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent) {
Toast t=Toast.makeText(context,intent.getStringExtra("info"),Toast.LENGTH_SHORT);
t.show();
}
}
*****oncreate*******
mainB=(Button)findViewById(R.id.mainB);
mainStopB=(Button)findViewById(R.id.mainStopB);
mainBroadB=(Button)findViewById(R.id.mainBroadB);
mainB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent=new Intent();
intent.setAction("CYCDT");
intent.putExtra("info","this is DTZC");
sendBroadcast(intent);
Log.v(tag,"this is send"+dtBroadcast);
}
});
mainBroadB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (dtBroadcast==null)
{
IntentFilter filter=new IntentFilter();
filter.addAction("CYCDT");
dtBroadcast=new DTBroadcast();
registerReceiver(dtBroadcast,filter);
Log.v(tag,"this is register");
}
}
});
mainStopB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (dtBroadcast!=null)
{
unregisterReceiver(dtBroadcast);
dtBroadcast=null;
Log.v(tag,"this is unregister"+dtBroadcast);
}
}
});
-----------------------------------------------------------------------
4.ContentProvider
作用:进程间进行数据交互 & 共享,即跨进程通信
1.进程内通信:
---------------extends SQLiteOpenHelper--------------------
//数据库名
private static final String DATABASE_NAME="cyc.db";
//表名
static final String USER_TABLE_NAME="user";
static final String JOB_TABLE_NAME="job";
//版本号
private static final int DATABASE_VERSION=1;
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("CREATE TABLE IF NOT EXISTS " + USER_TABLE_NAME + "(_id INTEGER PRIMARY KEY AUTOINCREMENT," + " name TEXT)");
sqLiteDatabase.execSQL("CREATE TABLE IF NOT EXISTS " + JOB_TABLE_NAME + "(_id INTEGER PRIMARY KEY AUTOINCREMENT," + " job TEXT)");
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
//数据库版本更新才调用
}
-----------------extends ContentProvider--------------------
private Context mContext;
DBHelper dbHelper=null;
SQLiteDatabase db=null;
private static final String MYPROVIDER="com.bn.mytest.providerT";
public static final int User_Code = 1;
public static final int Job_Code = 2;
private static final UriMatcher mMatcher;
static {
mMatcher=new UriMatcher(UriMatcher.NO_MATCH);
mMatcher.addURI(MYPROVIDER,"user", User_Code);
mMatcher.addURI(MYPROVIDER, "job", Job_Code);
}
public MyContentProvider()
{
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs)
{
// Implement this to handle requests to delete one or more rows.
return 0;
}
@Override
public String getType(Uri uri) {
// TODO: Implement this to handle requests for the MIME type of the data
// at the given URI.
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO: Implement this to handle requests to insert a new row.
// 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名
// 该方法在最下面
String table = getTableName(uri);
// 向该表添加数据
db.insert(table, null, values);
// 当该URI的ContentProvider数据发生变化时,通知外界(即访问该ContentProvider数据的访问者)
mContext.getContentResolver().notifyChange(uri, null);
// // 通过ContentUris类从URL中获取ID
// long personid = ContentUris.parseId(uri);
// System.out.println(personid);
return uri;
}
@Override
public boolean onCreate() {
// TODO: Implement this to initialize your content provider on startup.
mContext = getContext();
// 在ContentProvider创建时对数据库进行初始化
// 运行在主线程,故不能做耗时操作,此处仅作展示
dbHelper = new DBHelper(getContext());
db = dbHelper.getWritableDatabase();
// 初始化两个表的数据(先清空两个表,再各加入一个记录)
db.execSQL("delete from user");
db.execSQL("insert into user values(1,'Carson');");
db.execSQL("insert into user values(2,'Kobe');");
db.execSQL("delete from job");
db.execSQL("insert into job values(1,'Android');");
db.execSQL("insert into job values(2,'iOS');");
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO: Implement this to handle query requests from clients.
// 根据URI匹配 URI_CODE,从而匹配ContentProvider中相应的表名
// 该方法在最下面
String table = getTableName(uri);
// // 通过ContentUris类从URL中获取ID
// long personid = ContentUris.parseId(uri);
// System.out.println(personid);
// 查询数据
return db.query(table,projection,selection,selectionArgs,null,null,sortOrder,null);
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO: Implement this to handle requests to update one or more rows.
return 0;
}
private String getTableName(Uri uri){
String tableName = null;
switch (mMatcher.match(uri)) {
case User_Code:
tableName = DBHelper.USER_TABLE_NAME;
break;
case Job_Code:
tableName = DBHelper.JOB_TABLE_NAME;
break;
}
return tableName;
}
---------------------activity---------------------------------
/**
* 对user表进行操作
*/
// 设置URI
Uri uri_user = Uri.parse("content://com.bn.mytest.providerT/user");
// 插入表中数据
ContentValues values = new ContentValues();
values.put("_id", 3);
values.put("name", "Iverson");
// 获取ContentResolver
ContentResolver resolver = getContentResolver();
// 通过ContentResolver 根据URI 向ContentProvider中插入数据
resolver.insert(uri_user,values);
// 通过ContentResolver 向ContentProvider中查询数据
Cursor cursor = resolver.query(uri_user, new String[]{"_id","name"}, null, null, null);
while (cursor.moveToNext()){
Log.v(Tag,"query user:" + cursor.getInt(0) +" "+ cursor.getString(1));
// 将表中数据全部输出
}
cursor.close();
// 关闭游标
----------------------------------------------------------------------
详情参考:https://blog.csdn.net/carson_ho/article/details/76101093
SQLite详情参考:https://www.jianshu.com/p/8e3f294e2828