zoukankan      html  css  js  c++  java
  • Android的四大组件?(作用和用法)

    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

  • 相关阅读:
    Python爬虫教程-06-爬虫实现百度翻译(requests)
    Python爬虫教程-04-response简介
    Python爬虫教程-05-python爬虫实现百度翻译
    LeetCode——Balanced Binary Tree
    LeetCode——Min Stack
    LeetCode——Count and Say
    LeetCode——Invert Binary Tree
    LeetCode——Contains Duplicate II
    设计模式——桥接模式
    设计模式——责任链模式
  • 原文地址:https://www.cnblogs.com/CYCLearning/p/10092615.html
Copyright © 2011-2022 走看看