android入门到熟练(二)----活动
1.活动创建对于每一个后端java类(继承至Activity或者ActionBarActivity)代码都有一个方法需要被重写【onCreate】,
在此方法中可以加载界面资源文件或者绑定元素事件。
protected void onCreate(final Bundle savedInstanceState)//一般savedInstanceState为null,除非在返回界面时已经加载了值。
此处展示savedInstanceState不为空的时候获取其中保存的临时数据填充界面
if(savedInstanceState!=null){
String tempDate=savedInstanceState.getString("keyOne");
Toast.makeText(hellotest2.this,tempDate,Toast.LENGTH_SHORT).show();//界面上弹出提示内容
}
以下savedInstanceState中保存的数据其实是在该界面离开的时候触发的一个事件方法
@Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
String tempData="我们需要保存的数据";
outState.putString("keyOne",tempData);
}
加载layout文件方法:setContentView(R.layout.testhello);
绑定按钮方法:
Button buttonclose=(Button)findViewById(R.id.buttonClose);
buttonclose.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
Toast.makeText(hellotest2.this, "你点击了关闭程序按钮", Toast.LENGTH_SHORT).show();
finish();//活动的销毁
}
});
2.在androidManifest.xml中配置活动
<activity
android:name=".hellotest2"//此处指定具体活动类,由于在该文档已经制定了包的全名,所以只写上类名即可
android:theme="@android:style/Theme.Dialog"//只是当前的活动是主题类型的
android:launchMode="singleInstance"//指定该活动堆栈类型
android:label="@string/app_name" >//显示标题名称
<intent-filter>//以下2行代码指明该活动是主活动
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="shishi"/>//辅助信息
<data android:scheme="http"/>//表示该活动可以响应那种类型发服务,此处表示和浏览器一样可以打开网站
</intent-filter>
</activity>
ps:如果在androidManifest没有指定主活动,那么该程序可以被安装,只是看不到活动界面,此种程序作为第三方服务在内部提供给其他应用程序调用,如支付宝快捷支付。
3.创建菜单和响应菜单事件
首先在menu文件夹下面创建菜单资源,如下
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
<item android:id="@+id/action_settings" android:title="@string/action_settings" android:orderInCategory="100" app:showAsAction="never" />
<item android:id="@+id/action_remove" android:title="@string/remove" android:orderInCategory="100" app:showAsAction="never" />
</menu>
在菜单中添加了2个菜单选项,分别都定义了各自的ID
然后在活动java代码中编写如下方法:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);//加载具体的菜单文件,第二个参数表示要把资源添加到的菜单项
return true;
}
响应菜单按钮
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();//获取id值
switch (id)
{
case R.id.action_settings:
Toast.makeText(this,"你点击了设置菜单",Toast.LENGTH_SHORT).show();
break;
case R.id.action_remove:
Toast.makeText(this,"你点击了删除菜单",Toast.LENGTH_SHORT).show();
break;
default:
}
return super.onOptionsItemSelected(item);
}
4.Intent在活动间的使用
Intent是Android程序中组件之间进行交互的一种方式,可以指明当前组件要想执行的动作,还可以传递数据。它一般可用于启动活动,启动服务,发送广播等场景。Intent可以分为显示Intent和隐式Intent。代码如下:
【显示Intent】
String data="这个是我从上一个界面传过来的值哦!";
Intent intent=new Intent(hellotest2.this,SecondActivity.class);//显示Intent
intent.putExtra("data",data);//传递数据
savedInstanceState.putString("keyOne","数据1");
savedInstanceState.putDouble("keyTwo",3.44);
intent.putExtra("dataBundle",savedInstanceState);//传递Bundle
//startActivity(intent);//第一种启动方式,关闭活动后不会回调
startActivityForResult(intent,1);//第二种启动方式,关闭启动的活动后会调用现在活动的回调函数
//通过startActivityForResult启动活动后再关闭活动后回调函数,处理上一个活动的数据
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data)
{
switch (requestCode){
case 1:
if(resultCode==RESULT_OK){
String shuju= data.getStringExtra("dataint");
Toast.makeText(hellotest2.this,shuju,Toast.LENGTH_SHORT).show();
}
break;
default:
}
}
【隐式Intent】
表示不明确指定具体的上下文和启动的类,而是通过action和category等信息,交给系统去分析Intent,并且去找合适的活动在启动。
<activity
android:launchMode="singleInstance"
android:name=".SecondActivity">
<intent-filter>
<action android:name="lalaalal"/>//隐式Intent的action和这个匹配
<category android:name="android.intent.category.DEFAULT"/>//表示可以不指定任何category
<category android:name="shishi"/>//隐式Intent的category 和这个匹配
</intent-filter>
</activity>
只有Intent的action和category与配置文件都对应才能启动该活动,其中action只能指定一个而category可以指定多个如下:
Intent intent=new Intent("lalaalal");
intent.addCategory("shishi");
startActivity(intent);
5.Intent的其他隐式使用方法
启动浏览器:
Intent intent=new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
上面采用的直接调用android自带的浏览器,我们可以设置某个活动响应以上的Intent,而且还可以扩展,如下:
<activity android:name=".ThridActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="http"/>//指定响应http协议,此处除了http以外还有geo表示地理和tel表示电话
<data android:host="www.baidu.com"/>//指定响应百度
<data android:port="80"/>//指定响应80端口
<data android:mimeType=""/>//指定响应具体的文件类型
</intent-filter>
</activity>
只有Intent中携带的Data和android中<data>指定的data完全一致的情况活动才会响应对应Intent.
【拨打电话】
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
6.Intent传递数据
准备要传的数据
String data="这个是我从上一个界面传过来的值哦!";
Intent intent=new Intent(hellotest2.this,SecondActivity.class);
intent.putExtra("data",data);//传入数据
savedInstanceState.putString("keyOne","数据1");
savedInstanceState.putDouble("keyTwo",3.44);
intent.putExtra("dataBundle",savedInstanceState);//传入Bundle
//startActivity(intent);
startActivityForResult(intent,1);
在另外一个活动中接收数据
@Override
protected void onCreate(Bundle savedIndtanceState) {
super.onCreate(savedIndtanceState);
setContentView(R.layout.second_layout);
Intent intent = getIntent();//获取Intent,该Intent是在上一个活动中创建的
String data = intent.getStringExtra("data");//获取Intent中的数据
Bundle bundle=intent.getBundleExtra("dataBundle");//获取Intent中的Bundle
String bundleString=bundle.getString("keyOne");//获取Bundle中的值
Double bundleDouble=bundle.getDouble("keyTwo");
Log.i("我是提示数据",bundleString);//显示日志
Log.i("我是提示数据",bundleDouble.toString());
Button btnScdOne=(Button)findViewById(R.id.btnScdOne);
btnScdOne.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();//新建一个Intent,用于传递回之前的活动,在之前活动的回调中会使用
intent.putExtra("dataint", "999");
setResult(RESULT_OK, intent);//向上一个活动传递数据方法,在上一个活动中有一个回调函数onActivityResult
finish();
}
});
}
ps:在一个界面想获取以前的数据需要调用onSaveInstanceState,在界面加载的时候判断onCreate中的Bundle是否为空在取出数据,另一个是在当前活动启动一个新活动,在该活动结束时需要传递一些数据到本活动,我们需要在当前活动用startActivityForResult方法启动它,然后再本活动中定义一个回调函数onActivityResult,在此函数中获取销毁活动的数据。同时还要注意用户通过back键返回,那就要重写onBackPressed
@Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
String tempData="我们需要保存d数据";
outState.putString("keyOne",tempData);
}
@Override
public void onBackPressed(){
Intent intent=new Intent();
intent.putExtra("dataint", "999");
setResult(RESULT_OK, intent);//向上一个活动传递数据方法
finish();
}
除了Intent能保存数据Bundle 也能保存数据
7.活动周期
活动状态:运行状态,暂停状态,停止状态,销毁状态
活动生存周期:onCreate(),onstart(),onResume(),onPause(),onStop(),onDestroy(),onRestart()
8.活动的启动模式
standard,singleTop,singleTask,singleInstance,他们都是在androidManifest.xml中通过
<activity android:launchMode="singleInstance" android:name=".SecondActivity">设定的,
standard:每次启动都会重新建立一个活动放到堆栈中去
singleTop:如果在栈顶都是当前要创建的活动那么就不再创建活动
singleTask:如果发现在栈中已经有要创建的活动,那么把栈上面的活动依次出栈到需要的活动位置
singleInstance:为创建的活动单独创建一个栈,不受其他活动的影响,对于singleTask如果指定了不同的taskAffinity也会起到一个新的返回栈。该模式在其他程序需要对本程序的某个活动调用的场景使用。可以通过getTaskId()获取栈的标识号。
9.活动的最佳实践
知道当前在哪一个活动:添加一个类继承至Activity,然后其他说有的类都集成至该类,在onstart中Log显示出类名,getClass().getSimpleName()
一次性推出程序:方法是建立一个类,在类中定义一个Activity的List静态数组,并且实现3个方法,添加,删除,和循环读取活动在finish(),在基类活动或者每个活动启动时调用添加,销毁时调用删除,在某个事件触发退出程序是调用循环销毁。
启动的最佳写法:不管用startActivity或startActivityForResult启动一个活动,可能启动该活动需要依稀额外的数据,我们需要查看代码,最好的办法就是在需要启动的活动中添加一个静态方法,该方法有需要的启动上下文,以及各种数据:如下
在需要启动的活动类或者基类中添加如下代码
public static void actionStart(Context context,String data1,String data2)
{
Intent intent=new Intent(context,SecondActivity.class);//当前要启动的活动
intent.putExtra("paream1",data1);
intent.putExtra("paream2",data2);
context.startActivity(intent);
}
在要启动该活动的地方只需要调用该方法即可,不必麻烦再翻阅代码查看需要什么参数。