布局相关知识:
在代码中通过R.string.xxx可以获得该字符串的引用
setContentView(R.layout.activity_main);
在xml中通过@string/xxx可以获得该字符串的引用
在xml中通过@+id/id_name可以定义一个id
string可以替换成drawable、mipmap、layout等
一、Activity
1.活动的生命周期
onCreate ()
onStart() [Activity不可见]
onResurme [Acitvity可见,处于运行状态]
onPause [Activity可见,处于暂停状态]
onStop [Activity不可见,处于停止状态]
onDenstroy [Activity被销毁]
2.活动异常终止时,临时数据的保存
重载onSaveInstanceState()回调方法,该方法在活动被回收前一定会被调用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState !=null){ //判断有无数据被保存
String tempData = savedInstanceState.getString("data_key");//根据键来提取值
Log.d(TAG,tempData);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
String tempData = "Something you just typed";
outState.putString("data_key",tempData);//通过键值对保存临时数据
}
3.使用显式Intent启动Activity
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent); //startActivity方法
4.使用隐式Intent启动Activity
在第二个活动的AndroidManifest.xmml里面添加
<activity android:name=".SecondActivity" >
<intent-filter>
<action android:name="com.example.activitytest.ACTION_START"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
直接执行以下方法就可以进行活动切换:
Intent intent2 = new Intent("com.example.activitytest.ACTION_START");
startActivity(intent2);
<action>和<category>需要同时匹配上才能启动响应,为何这里只匹配了action,就可以了呢?
因为Intent2如果没有addCategory对应的category,它会默认执行 intent2.addCategory("android.intent.category.DEFAULT");
即上面的执行活动切换的方式即为:
Intent intent2 = new Intent("com.example.activitytest.ACTION_START");
intent2.addCategory("android.intent.category.DEFAULT");
startActivity(intent2)
使用隐式Intent的作用:可以在当前的活动里面去启动其他app的活动,比如调用浏览器、拨号界面等。
5.通过Intent向下一个活动传递数据
//在第一个Activity里写
String data = "Hello SecondActivity";
Intent intent = new Intent(this, SecondActivity.class);//显示启动Activity
intent.putExtra("extra_data",data);//extra_data为键,变量data为值
startActivity(intent); //startActivity方法
//在第二个Activity里写
Intent intent = getIntent(); //通过getIntent()获取用于启动SecondActivity的Intent
String data = intent.getStringExtra("extra_data");//调用getStringExtra()方法获取传递的数据
6.返回数据给上一个活动
//在第一个Activity里写
Intent intent = new Intent(this, SecondActivity.class);//显示启动Activity
startActivityForResult(intent,1); //用startActivityForResult方法启动SecondActivity,第二个参数1为唯一码,用于标记数据的传递
//在第二个Activity里写
Intent intent = new Intent();//该intent只用于传递数据,没有指定任何"意图
intent.putExtra("data_return","Hello FirstActivity");//data_return为键,第二个参数为值
setResult(RESULT_OK,intent);//setResult()方法专门用于给上一活动返回数据;第一个参数用于写处理结果,一般只写RESULT_OK或RESULT_CANCELED
finish();//销毁当前活动
//用startActivityForResult启动SecondActivity,在SecondActivity被销毁以后会回调上一个活动的onActivityResult()方法,
//因此在FirstActivity里需要重写onActivityResult()方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case 1: // requestCode为之前的标记
if(resultCode == RESULT_OK){ //resultCode为处理结果
String returnData = data.getStringExtra("data_return");
Log.d("LOUHN",returnData);
}
}
break;
... ...
}
----------------------------------------------------------
//上面的方法都是调用自定义按钮来进行跳转的,如果用于在SecondActivity,
//通过按下Back按键来返回上一个Activity,并且也要返回数据,
//则可以通过在SecondActivity中重写onBackPressed()方法来实现
@Override
public void onBackPressed(){
Intent intent = new Intent();
intent.putExtra("data_return","Hello FirstActivity");
setResult(RESULT_OK,intent);
finish();
}
//这样用户按下Back按键回去执行onBackPressed里面的方法
7.活动的启动模式
standard 标准模式
singleTop 栈顶复用模式
singleTask 栈内复用模式
singleInstance 单实例模式
修改AndroidManifast.xml中Activity启动模式
standard 标准模式
singleTop 栈顶复用模式
如果FirstActivity跳转的是同一个活动FirstActivity,则不会onCreate一个新的活动,而是保留在原来的活动上。
如果FirstActivity并未在栈顶位置,这时再启动FirstActivity,还是会创建新的FirstActivity活动
singleTask 栈内复用模式
FirstActivity启动SecondActivity,SecondActivity再启动FirstActivity时候,SecondActivity会直接出栈,并执行了SecondActivity的onDestroy()方法。
FirstActivity处于了栈顶位置,此时按下back按键程序就直接退出了,并不会跳转到SecondActivity活动。
singleInstance 单实例模式
如下图所示,把SecondActivity设置为singleInstance模式,所有SecondActivity与其他Activity处于不同的栈中,则在ThirdActivity返回时候的时候,不会返回到SecondActivity上,而是会返回到同一个栈的FirstActivity上,等一个栈的Activity全部出完后,才会回到另一个栈上,跳到SecondActivity
三、广播机制
标准广播:一种完全异步执行的广播,广播发出后所有广播接收器几乎会同时接收到这条广播
有序广播:一种同步执行的广播,广播发出后同一时刻只会有一个广播接收器能够接收到这条广播,且可以截断广播,让后续的广播接收器无法收到广播消息
1.动态接收系统广播,监听网络状态变化
实现步骤:
- 实例化IntentFilter类
- 给IntentFilter的实例添加一个action
- 实例化创建好的广播接收器
- 注册广播
- 在广播接收器重写的方法中写对应的逻辑
- 取消注册
注意:动态注册的广播接收器一定都要取消注册,这里是在onDestroy()里通过调用unregisterReveiver()方法实现的
public class MainActivity extends AppCompatActivity {
/**
* 动态注册并使用广播接收器
*/
private IntentFilter intentFilter;
private NetChangeReceiver netChangeReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_broad_cast);
intentFilter = new IntentFilter();
// 添加action,当网络情况发生变化时,系统就是发送一条值为android.net.conn.CONNECTIVITY_CHANGE的广播
intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
netChangeReceiver = new NetChangeReceiver();
// 注册广播
registerReceiver(netChangeReceiver, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
// 取消注册,动态注册的广播接收器一定要取消注册才行
unregisterReceiver(netChangeReceiver);
}
// 创建一个名为NetChangeReceiver的广播接收器
class NetChangeReceiver extends BroadcastReceiver {
// 当接收到广播,便执行onReceive()方法
@Override
public void onReceive(Context context, Intent intent) {
// 判断当前的网络情况,并给出提示
// 通过getSystemService()方法得到ConnectivityManager的实例
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
// 通过ConnectivityManager得到NetworkInfo的实例
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isAvailable()) {
Toast.makeText(context, "当前网络连接正常", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "无网络连接", Toast.LENGTH_SHORT).show();
}
}
}
}
访问系统的网络状态就需要声明权限:
<!-- 访问系统的网络状态 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
2、静态注册广播实现开机自启
与动态注册广播的区别:动态注册广播只能在程序启动后才能接受到广播,因为注册逻辑是写在onCreate()上的。