安卓开发(二) 四大组件—活动

本文主要记录第一行代码中安卓开发流程总结和个人安卓APP开发中遇到的实战问题解决方案

大纲

活动(Activity)

活动包含用户界面的组件,用于与用户交互,一个应用中可以包含多个活动

活动用法

1.创建活动:用于调用布局和元素用来与用户交互
创建一个空活动(Add No Activity),可在app/src/main/java/com.example.activitytest创建活动(New-Activity-EmptyActiviy)

创建的是EmptyActivity十分简洁,在onCreate()中仅调用了父类的onCreate()方法

2.创建布局和元素:活动对应的布局用来显示界面内容
创建一个布局,在app/src/main/res下创建一个存储布局文件的文件夹layout,然后在里面添加一个布局文件(New-Layout resource file)
创建一个Button元素,指定id和属性

3.活动加载布局和元素:使用setContentView(layoutId)方法加载布局
layoutId可在R文件中找到,因为项目中任何资源都会在R文件中生成对应的资源id,调用方式为R.ResourceCategory.FileName如layout下的firstLayout为R.layout.firstLayout

4.注册活动:AS在创建活动时会自动在AndroidManifest.xml中帮我们注册活动或其他组件
标签中使用标签注册活动

1
2
3
4
5
6
7
<activity android:name=".FirstActivity"  //指定注册活动名
android:label="This is FirstActivity"> //活动标题栏内容
<intent-filter>
<action android:name="android.intent.action.MAIN" /> //设置主活动
<category android:name="android.intent.category.LAUNCHER" /> //设置主活动
</intent-filter>
</activity>

简单的活动

1.Toast(短小消息提醒):
Toast.makeText(Context,Msg,Time).show()
1
2
3
4
5
6
7
8
9
//FirstActivity.java
//在活动中设置Button监听点击事件触发Toast
Button button1=(Button)findViewById(R.id.ButtonFirst);
button1.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
Toast.makeText(FirstActivity.this,"FirstToast!", Toast.LENGTH_SHORT).show();
}
});


2.Menu(菜单):
创建菜单资源文件,res->New directory->menu,menu->New->Menu resource file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//main.xml
<item //菜单项
android:id="@+id/addItem"
android:title="Add"/>
<item
android:id="@+id/removeItem"
android:title="Remove"/>

//FirstActivity.java

@Override
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.main,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId()){
case R.id.addItem:
Toast.makeText(this,"Add!", Toast.LENGTH_SHORT).show();
break;
case R.id.removeItem:
Toast.makeText(this,"Remove!", Toast.LENGTH_SHORT).show();
break;
default:
}
return true;
}


3.finish()销毁活动:

活动跳转(Intent)

Intent是Android中组件之间进行交互的方式,可用于指明当前组件动作和组件间传递数据,一般用于启动互动、启动服务、发送广播等

显式Intent

显式Intent的意图明显,如Intent(Context,Class),Context为背景上下文,Class为目标活动
启动活动可以用startActivity(Intent)

隐式Intent(程序内活动)

隐式Intent意图不明显,不指定启动函数而是由系统分析出合适活动去启动
使用Intent的另一个构造函数Intent(ActionName)/intent.addCategory(CategoryName),ActionName和CategoryName会在活动注册标签中寻找匹配的活动

1
2
3
4
5
6
7
//AndroidManifest.xml
<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(程序间活动)

隐式Intent还可以启动其他程序的活动,使得Android程序间功能共享成为可能
如启动安卓内置浏览器打开网页、启动拨打号码活动等

Intent代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
//显示Intent(Context,Class)
Intent intent=new Intent(FirstActivity.this,SecondActivity.class);

//隐式Intent(ActionName)+intentObj.addCategory(CategoryName)
Intent intent=new Intent("com.example.activitytest.ACTION_START");
intent.addCategory("android.intent.category.DEFAULT");

//隐式Intent程序间活动
Intent intent=new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));

//启动活动
startActivity(intent);

活动传递数据(Intent)

1
2
3
4
5
6
7
8
9
//传递数据 intent.putExtra(key,value);
String data="Hello Next Activity!";
Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
intent.putExtra("passData",data);
startActivity(intent);

//取出数据 getIntent()+intent.getStringExtra(key)
Intent intent=getIntent();
String data=intent.getStringExtra("passData");

活动返回数据(startActivityForResult)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//启动活动时用startActivityForResult(Intent,Code)
//Code为请求码
Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
startActivityForResult(intent,1);

//被启动活动将要传递的数据放在intent中并setResult(Status,Intent)
//Status为活动处理结果 RESULT_OK/RESULT_CANCALED
//这段代码可以放在活动元素中或者onBackPressed()中(用户按back键销毁活动)
Intent intent=new Intent();
intent.putExtra("dataReturn","Hello Previous Activity!");
setResult(RESULT_OK,intent);

//被启动的活动销毁后会调用上一个活动的onActivityResult(Code,Status,Intent)
//Code为请求码,Status为活动处理结果,Intent为带有数据的返回Intent
@Override
protected void onActivityResult(int code,int status,Intent data)
{
switch(code){
case 1:
if(status==RESULT_OK) {
String returnData=data.getStringExtra("dataReturn");
}
break;
default:
}
}

活动的生命周期

Android使用任务(Task)来管理活动的,一个任务就是一组存放在返回栈中的活动集合

活动的状态

运行状态:栈顶活动

暂停状态:不处于栈顶但是仍然可见的活动

停止状态:不处于栈顶并且不可见的活动

销毁状态:出栈的活动

活动改变状态函数

Tips:活动从停止状态变为运行状态,有两条路径,取决于停止状态时活动是否被系统回收,若已经被系统回收,则返回到活动时需要调用onCreate()重新创建活动,否则调用onRestart()重新启动活动

活动回收时保存数据

活动在被系统回收时若需要保存当前活动数据,可以在onSaveInstanceState()函数中使用Bundle数据类型的putString/putInt(key,value)等保存数据,函数保证活动回收前一定被调用

1
2
3
4
5
6
7
8
9
10
11
12
13
//保存数据
@Override
protect void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
outState.putString(key,value);
}
//取出数据
@Override
protected void onCreate(Bundle savedInstanceState){
if(savedInstanceState!=null){
String data=savedInstanceState.getSrring(key);
}
}

活动启动模式

通过在AndroidManiFest.xml中给标签指定android:launchMode属性指定活动启动模式

standard模式:活动每次启动都创建一个新的活动实例

singleTop模式:处于栈顶的活动启动不会创建新的活动实例

singleTask模式:栈内的活动会被调用至栈顶并弹出这个活动以上的所有活动

singleInstance:创建一个单独栈启动活动,其他活动均调用这个栈内的活动实例

活动小技巧

可以创建一个活动基类BaseActivity添加一些方法辅助我们编写活动

1
2
3
4
5
6
7
public class BaseActivity extends AppCompatActivity{
@Override
protect void onCreate(Bundle saveInstanceState){
super.onCreate(saveInstanceState);
Log.d("NowActivity",getClass().getSimpleName()); //打印当前创造的活动名
}
}

被启动的活动若需要传递参数启动可以编写一个函数用于启动活动时调用
1
2
3
4
5
6
7
8
9
10
//如启动活动需传递一个String值
public static void actionStart(Context context,String data)
{
Intent intent=new Intent(context,startActivityName.class);
intent.putExtra(key,data);
context.startActivity(intent);
}
//别的活动就可以调用这个函数来启动活动
String NeedData;
startActivityName.actionStart(FirstActivity.this,NeedData);