总结《第一行代码》Android学习笔记(二)活动Activity
- 活动(Activity)
- Toast的使用
- Menu的使用
- 销毁活动
- 使用Intent实现活动的转移和数据传递
- 1.使用显式Intent
- 2.使用隐式Intent
- 3.隐式Intent的更多用法
- 4.向下一个活动传递数据
- 5.向上一个活动传递数据
- 活动的生命周期
- 活动的回收后数据丢失问题
- 活动的启动模式
- 1.standard
- 2.singleTop
- 3.singleTask
- 4.singleInstance
- 活动的优化
- 1.获取当前活动名
- 2.随时随地退出程序
- 3.启动带参数的活动
活动(Activity)
Toast的使用
Toast.makeText(FirstActivity.this,"You clicked Button 1",Toast.LENGTH_SHORT).show();
Menu的使用
1.res目录下新建名为main的Menu resource file文件。
2.在main.xml添加两个菜单项:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/add_item"
android:title="Add"/>
<item android:id="@+id/remove_item"
android:title="Remove"/>
</menu>
3.在活动中重写onCreateOptionsMenu()给活动创建菜单:
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
4.在活动中重写onOptionsItemSelected()来定义菜单项的响应事件:
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.add_item:
Toast.makeText(FirstActivity.this,"You clicked add",Toast.LENGTH_SHORT).show();
break;
case R.id.remove_item:
Toast.makeText(FirstActivity.this,"You clicked remove",Toast.LENGTH_SHORT).show();
break;
default:
}
return true;
}
销毁活动
通过finish()来销毁当前活动:
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
使用Intent实现活动的转移和数据传递
1.使用显式Intent
点击button1从FirstActivity转移到SecondActivity:
button1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivity(intent);
}
});
2.使用隐式Intent
先在androidManifest中为SecondActivity指定活动能够响应的action和category:
<activity
android:name=".SecondActivity"
android:label="This is SecondActicity">
<intent-filter>
<action android:name="second action"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="second category"/>
</intent-filter>
</activity>
然后修改按钮点击事件:
button1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Intent intent = new Intent("second action");
intent.addCategory("second category");
startActivity(intent);
}
});
3.隐式Intent的更多用法
(1)调用系统浏览器并且打开指定网页:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
(2)调用系统拨号界面并且输入10086:
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
(3)调用系统谷歌地图并显示地理位置:
geo:latitude,longitude
显示给定经度和纬度处的地图。
示例:"geo:47.6,-122.3"
geo:latitude,longitude?z=zoom
按特定缩放级别显示给定经度和纬度处的地图。缩放级别为 1 时显示以给定纬度、经度为中心的全球地图。 最高(最精确)缩放级别为 23。
示例:"geo:47.6,-122.3?z=11"
geo:0,0?q=lat,lng(label)
显示给定经度和纬度处带字符串标签的地图。
示例:"geo:0,0?q=34.99,-106.61(Treasure)"
geo:0,0?q=my+street+address
显示“我的街道地址”的位置(可能是具体地址或位置查询)。
示例:"geo:0,0?q=1600+Amphitheatre+Parkway%2C+CA"
注:geo URI 中传递的所有字符串都必须编码。 例如,字符串 1st & Pike, Seattle 应编码为 1st%20%26%20Pike%2C%20Seattle。字符串中的空格可使用 %20 编码或替换为加号 (+)。
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("geo:47.6,-122.3"));
startActivity(intent);
4.向下一个活动传递数据
在SecondActivity中通过putExtra()将数据保存在intent中,然后将intent转移到ThirdActivity中:
String data = "123456";
Intent intent = new Intent(SecondActivity.this,ThirdActivity.class);
intent.putExtra("extra_data",data);
startActivity(intent);
在ThirdActivity中通过getIntent()获取启动ThirdActivity的intent,然后调用getStringExtra()获取传递的数据:
Intent intent = getIntent();
String data = intent.getStringExtra("extra_data");
Log.d("ThirdActivity", "onCreate: "+data);
5.向上一个活动传递数据
在SecondActivity中点击按钮跳转到ThirdActivity:
button3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(SecondActivity.this,ThirdActivity.class);
startActivityForResult(intent,1);
}
});
在ThirdActivity中点击按钮将数据传递给SecondActivity:
button4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("data_return","666");
setResult(RESULT_OK,intent);
finish();
}
});
在SecondActivity中重写onActivityResult():
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
switch (requestCode){
case 1:
if (resultCode==RESULT_OK){
String returnedData = data.getStringExtra("data_return");
Log.d("SecondActivity", "onActivityResult: "+returnedData);
}
}
}
活动的生命周期
活动的四种状态:运行状态,暂停状态,停止状态和销毁状态。
运行状态onResume():活动处于返回栈的栈顶时,活动处于运行状态。
暂停状态onPause():活动不处于返回栈的栈顶但仍然可见时,活动处于暂停状态。
停止状态onStop():活动不处于返回栈的栈顶且完全不可见时,活动处于停止状态。
销毁状态onDestory:活动从返回栈中移除后处于销毁状态。
活动的回收后数据丢失问题
因为活动被回收前一定会调用onSaveInstanceState()回调方法,因此重写onSaveInstanceState()来保存数据:
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
String tempData = "abc";
outState.putString("data_key",tempData);
}
然后在onCreate()中取出数据:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("MainActivity", "onCreate");
setContentView(R.layout.activity_main);
if(savedInstanceState != null){
String tempData = savedInstanceState.getString("data_key");
Log.d("MainActivity", "tempData");
}
}
活动的启动模式
活动的启动模式一共有4种:standard、singleTop、singleTask和singleInstance。
活动的启动模式可在AndroidManifest.xml中活动中通过修改launchMode来修改:
<activity
android:name=".FirstActivity"
android:label="This is FirstActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHNER" />
</intent-filter>
</activity>
1.standard
standard是活动默认启动模式,启动新活动时不会在乎这个活动是否已经在返回栈中入栈,每次启动都会创建该活动的一个新的实例。
2.singleTop
singleTop在创建活动时会判断栈顶是否为新的活动,若是新的活动则会创建,若不是新的活动则不会创建。
3.singleTask
singleTask在创建活动时会判断返回栈里是否存在该活动,若不存在则会创建,若存在则出栈该活动上的所有活动。
4.singleInstance
这个启动模式能使不同的返回栈公用同一个活动实例。例如FirstActivity和ThirdActivity都是standard启动模式,SecondActi-vity是singleInstance启动模式,当FirstActivity跳转到SecondActivity时会新建两个返回栈,可使用getTaskID()方法观察栈的序号,然后SecondActivity跳转到ThirdActivity,当点Back键时直接返回FirstActivity然后再返回SecondActivity。
活动的优化
1.获取当前活动名
新建BaseActivity类然后继承自AppComatActivity,重写onCreate()方法:
public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("BaseActivity", getClass().getSimpleName());//获取活动名
}
}
然后将需要启动的活动继承自BaseActivity。
2.随时随地退出程序
新建ActivityCollector类:
public class ActivityCollector {
public static List<Activity> activities = new ArrayList<>();
public static void addActivity(Activity activity){//定义添加活动方法
activities.add(activity);
}
public static void removeActivity(Activity activity){//定义删除活动方法
activities.remove(activity);
}
public static void finishAll(){//定义结束程序方法
for (Activity activity : activities){
activity.finish();
}
activities.clear();
}
}
修改BaseActivity:
public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("BaseActivity", getClass().getSimpleName());
ActivityCollector.addActivity(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);
}
}
调用直接退出程序方法:
button4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityCollector.finishAll();//结束程序
android.os.Process.killProcess(android.os.Process.myPid());//结束进程
}
});
3.启动带参数的活动
在SecondActivity中添加actionStart()方法:
public static void actionStart(Context context,String data1,String data2){
Intent intent = new Intent(context,SecondActivity.class);
intent.putExtra("param1",data1);
intent.putExtra("param2",data2);
context.startActivity(intent);
}
FirstActivity跳转到SecondActivity:
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
SecondActivity.actionStart(FirstActivity.this,"sjl","qmt");
}
});