Android开发基础知识整理之四大组件

来源:互联网 发布:mac os x和ios区别 编辑:程序博客网 时间:2024/04/29 06:01

最近郭霖大神的第二行代码出版了,我也是第一时间买到了这本书,并且刷完了一遍。作为安卓开发的初学者,想梳理一下书中的主要知识点,以作备忘之用。这也是我的第一篇博客,希望在以后的学习和工作中可以经常记录一些内容,供自己参考,也能和大家分享与交流。

一、 Acitivity

(一) 用法

1. 加载布局

setContentView(R.layout.activity_main);

2. AndroidManifest中注册

<activity android:name=".FirstActivity"        android:lable="This is FirstActivity">        <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.category.LAUNCHER" />        </intent-filter></activity>

3. 使用Menu

(1) res文件夹下新建menu文件夹,在其中新建菜单文件main.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android">    <item        android:id="@+id/add_item"        android:title="Add"/>    <item        android:id="@+id/remove_item"        android:title="Remove"/></menu>

(2) 重写 onCreateOptionsMenu() 使菜单显示出来

重写快捷键Ctrl+O

@Overridepublic boolean onCreateOptionsMenu(Menu menu) {    getMenuInflater().inflate(R.menu.main, menu);    return true;}

(3) 重写 onOptionsItemSelected() 定义菜单响应事件

调用item.getItemId()判断点击的是哪个菜单项。

@Overridepublic boolean onOptionsItemSelected(MenuItem item) {    swith (item.getItemId()) {     case R.id.add_item:        Toast.makeText(this, "add", Toast.LENGTH_SHORT).show();        break;    case R.id.remoce_item:        Toast.makeText(this, "remove", Toast.LENGTH_SHORT).show();        break;    default:    }    return true;}

4. 销毁活动

调用 finish() 方法。

(二) 使用Intent

1. 显式Intent

构造方法接收两个参数:( context提供启动活动的上下文,class指定想启动的目标活动 )

Intent intent = new Intent(FirstActivity.this, SecondActivity.class); startActivity(intent);

2. 隐式Intent

指定action和category等信息。action只能指定一个,category可指定多个。

Intent intent = new Intent("com.example.activitytest.ACTION_START");intent.addCategory("com.example.activitytest.MY_CATEGORY");startActivity(intent);

3.隐式Intent启动其他程序

// 浏览器Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://www.baidu.com"));startActivity(intent);
//拨号Intent intent = new Intent(Intent.ACTION_DIAL);intent.setData(Uro.parse("tel:10086"));startActivity(intent);

4.向下一个活动传递数据

  • 传入:调用 putExtra(),接收两个参数分别为键值。
  • 取出:首先调用 getIntent() 获取Intent,再根据传递的数据类型,调用 getStringExtra()getIntExtra() 等方法。
//传入String data = "Hello SecondActivity";Intent intent = new Intent(FirstActivity.this, SecondActivity.class);Intent.putExtra("extra_data",data);startActivity(intent);//取出Intent intent= getIntent();String data = intent.getStringExtra("extra_data");Log.d("SecondActivity", data);

5. 返回数据给上一个活动

  • 启动活动:使用 startActivityForResult() ,它接收两个参数 ( Intent, 请求码 )。
  • 返回数据:new出一个Intent putExtra() 放入数据,调用 setResult(RESULT_OK, intent) ,最后销毁当前活动。
  • 获取数据:重写回调的 onActivityResult() 方法,检查requestCode和resultCode,调用 data.getStringExtra() 取出数据。
// 获取数据@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {    switch (requestCode) {        case 1:            if (resultCode == RESULT_OK) {                String returnedData = data.getStringExtra("data_return");                Log.d("FirstActivity", returnedData);            }            break;        default:    }}

(三) 活动的生命周期

  • 四种状态:运行、暂停、停止、销毁。

  • 三种生存期:

    • 完整生存期 onCreate() — onDestroy()
    • 可见生存期 onStart() — onStop()
    • 前台生存期 onResume() — onPause()

生命周期图

程序状态的恢复:

  • 保存:重写 onSaveInstanceState() ,调用Bundle的 putString()putInt() 等方法传入键值保存数据。
  • 恢复:savedInstanceState.getString()
//保存@Overrideprotected void onSaveInstanceState(Bundle outstate) {    super.onSaveInstanceState(outState);    String tempData = "Something";    outState.putString("data_key", tempData);}//恢复 (onCreate中)if (savedInstanceState != null) {    String tempData = savedInstanceState.getString("data_key");    Log.d(TAG, tempData);}

(四) 活动的启动模式

  • 在AndroidManifest.xml中修改activity标签的 android:launchMode=""
  • standard
    standard

  • singleTop
    singleTop

  • singleTask
    singleTask

  • singleInstance
    singleInstance

二、 Broadcast

(一) 简介

广播的类型:主要分为标准广播和有序广播。

  • 标准广播:异步执行,同时接收没有先后顺序,无法截断。
  • 有序广播:同步执行,有先后顺序,可被截断。

广播接收器的生命周期:只有十秒左右,如果在 onReceive() 内做超过十秒的事情,就会报ANR(Application No Response) 程序无响应的错误信息。

(二) 接收系统广播

1. 动态注册

新建一个类,让它继承自BroadcastReceiver,并重写父类的 onReceive() 方法。
调用 registerReceiver(receiver实例, intentFileter) 进行注册,最后需要调用 unregisterReveiver(receiver实例) 取消注册。

public class MainActivity extends AppcompatActivity {    private IntentFilter intentFilter;    private NetworkChangeReceiver networkChangeReceiver;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        intentFileter = new IntentFilter();        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");        networkChangeReceiver = new NetworkChangeReceiver();        registerReceiver(networkChangeReceiver, intentFilter);    }    @Override    protected void onDestroy() {        super.onDestroy();        unregisterReceiver(networkChangeReceiver);    }    class NetworkChangeReceiver extends BroadcastReceiver {        @Override        public void onReceive(Context context, Intent intent) {            ConnectivityManager connectionManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE;            NetworkInfo networkInfo = connectionManager.getActiveNetworkInfo();            if(networkInfo != null && networkInfo.isAvailable()) {            Toast.makeText(context, "network is available", Toast.LENGTH_SHORT).show();            } else {            Toast.makeText(context, "network is unavailable", Toast.LENGTH_SHORT).show();            }        }    }}

2. 静态注册

可以让程序在未启动的状态下接收到广播。
新建BroadcastReceiver,在 onReceive() 中写入相应逻辑,并在AndroidManifest.xml中注册,<intent-filter> 标签中添加相应action。

public class BootCompleteReceiver extends BroadcastReceiver {       @Override    public void onReceive(Context context, Intent intent) {        Toast.makeText(context, "Boot Complete", Toast.LENGTH_LONG).show();    }}
    ...    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>    <application            ...>        <receiver            android:name=".BootCompleteReceiver"            android:enabled="true"            android:exported="true">            <intent-filter>                    <action android:name="android.intent.action.BOOT_COMPLETED" />            </intent-filter>        </receiver>    </application>

(三) 发送自定义广播

1. 发送标准广播

构建Intent对象,把要发送的广播的值传入,调用context的 sendBroadcast(intent) 发送广播。

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

2. 发送有序广播

  • 发送广播使用 sendOrderedBroadcast(intent, null) 方法。
  • AndroidManifest中通过 android:priority 属性给广播接收器设置优先级,优先级高的先收到广播。
  • onReceive() 中调用 abortBroadcast() 可将广播截断。
// 发送广播Intent intent = new intent("com.example.broadcasttest.MY_BROADCAST");sendOrderedBroadcast(intent,null);
// 设置优先级<intent-filter android:priority="100">        <action android:name="com.example.broadcasttest.MY_BROADCAST" /></intent-filter>
// 截断广播@Overridepublic void onReceive(Context context, Intent intent) {        Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();        abortBroadcast();}

(四) 使用本地广播

使用本地广播机制发出的广播只能在应用程序内部传递,并且广播接收器也只能接收来自本程序的广播,保证安全性。
借助LocalBroadcastManager对广播进行管理,和动态注册广播几乎一样。

  • 获取localBroadcastManager实例:调用 LocalBroadcastManager.getInstance(this)
  • 发送本地广播:调用 localBroadcastManager.sendBroadcast(intent)
  • 注册和取消注册广播接收器:新建一个LocalReceiver,调用 localBroadcastManager.registerReceiver(localReceiver, intentFilter)localBroadcastManager.unregisterReceiver(localReceiver)

注意:本地广播无法通过静态注册方式来接收。

三、 Service

(一) 基本用法

1. 定义一个服务

新建Myservice,重写 onCreate()onStartCommand()onDestroy() 三个方法,并在AndroidManifest中注册。

  • onCreate():服务创建时调用。
  • onStartCommand():每次服务启动时调用,主要处理逻辑写在此处。
  • onDestroy():服务销毁时调用,回收不再使用的资源。
public class MyService extends Service {    ...    @Override    public void onCreate() {        super.onCreate();    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        return super.onStartCommand(intent, flags, startId);    }    @Override    public void onDestroy() {        super.onDestroy();    }}

2. 启动和停止服务

  • 活动中:借助Intent,调用 startService(startIntent)stopService(stopIntent) 来启动和停止服务。
  • 服务中:任何位置调用 stopSelf() 方法让服务自己停止。

3. 活动和服务进行通信

  • 在Service中创建一个专门的Binder对象进行管理,在 onBind() 方法中返回这个实例。
  • 在Activity中创建ServiceConnection的匿名类,重写 onServiceConnected()onServiceDisconnected 方法,它们分别在活动与服务成功绑定和解除绑定时调用。
    • onServiceConnected() 中获得Binder的实例,可以调用其中的任何公共方法。
    • 调用 bindservice(Intent, ServiceConnection实例, BIND_AUTO_CREATE) 绑定并自动创建服务。
    • 调用 unBindService(ServiceConnection实例) 解除绑定。
public class MyService extends Service {    private DownloadBinder mBinder = new DownloadBinder();    class DownloadBinder extends Binder {        public void startDownload() {            Log.d("MyService", "startDownload executed");        }        public int getProgress() {            Log.d("MyService", "getProgress executed");            return 0;        }    }    @Override    public IBinder onBind(Intent intent) {        return mBinder;    }    ...}
public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private MyService.DownloadBinder downloadBinder;    private ServiceConnection connection = new ServiceConnection() {        @Override        public void onServiceDisconnected(ComponentName name) {        }        @Override        public void onSeviceConnected(ComponentName name, Ibinder service) {            downloadBinder = (MyService.DownloadBinder) service;            downloadBinder.startDownload();            downloadBinder.getProgress();        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        ...        Button bindService = (Button) findViewById(R.id.bind_service);        Button unbindService = (Button) findViewById(R.id.unbind_service);        bindService.setOnClickListener(this);        unbindService.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch(v.getId()) {            ...            case R.id.bind_service:                Intent bindIntent = new Intent(this, MyService.class);                bindService(bindIntent, connection, BIND_AUTO_CREATE);                break;            case R.id.unbind_service:                unbindService(connection);                break;            default:                break;        }    }}

(二) 服务的生命周期

Service有两种使用方法:

  • 以调用 Context.startService() 启动,以调用 Context.stopService() 结束。
  • 以调用 Context.bindService() 方法建立,以调用 Context.unbindService() 关闭。

服务的生命周期

(三) 服务的更多技巧

1. 使用前台服务

  • 能使服务一直保持运行,并常驻状态栏。
  • onCreate()中:构建一个Notification对象后调用 startForeground(通知id, Notification对象) 让服务成为前台服务。
public class MyService extends Service {    ...    @Override    public void onCreate() {        super.onCreate();        Intent intent = new Intent(this, MainActivity.class);        PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);        // 获取用于启动Activity的PendingIntent,接收四个参数:上下文、请求码、Intent、flag参数        Notification notification = new NotificationCompat.Builder(this)                .setContentTitle("This is content title")                .setContentText("This is content text")                .setWhen(System.currenTimeMillis())                .setSmallIcon(R.mipmap.ic_launcher)                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_Launcher))                .setContentIntent(pi)                .bulid();        startForeground(1, notification);    }    ...}

2. 使用IntentService

  • 可以简单的创建一个异步的、会自动停止的服务。
  • 新建MyIntentService类继承自IntentService:
    • 首先提供一个无参的构造函数,并在其内部调用父类的有参构造函数;
    • 实现 onHandleIntent() 抽象方法,在其中处理具体逻辑。
public class MyIntentService extends IntentService {    public MyIntentService() {        super("MyIntentService"); // 调用父类的有参构造函数@Override    protected void onHandleIntent(Intent intent) {        // 处理具体逻辑,这里打印当前线程id        Log.d("MyIntentService", "Thread is" + Thread.currentThread().getId());    }    @Override    public void onDestroy() {        super.onDestroy();        Log.d("MyIntentService", "onDestroy executed");    }}

四、 Content Provider

待填坑

1 0