您的位置:首页 > 其它

安卓基础第六天(四大组件之Activity)

2018-02-21 03:12 671 查看
Activity 是Android 四大组件之一,它用于展示界面。

是一个负责与用户交互的组件,可以通过setContentView(View)来显示指定控件。

Activity 之间通过Intent 进行通信。### Activity之间的跳转

Activity清单配置

定义类继承Activity

在AndroidManifest.xml 的节点中声明

application中lable指程序的名字,

activity中的lable是指activity 的名字

name 属性::包名.Activity 类名

包名如果与mainfest 的package 一致,可以用“.”代替。或者不写

Intent-filter 子节点:

- 添加意图过滤,可以通过隐式意图启动。

- 可以在桌面生成快捷方式,应用程序的入口

如果此activity还指定了以下filter那么这个界面就会在桌面创建快捷方式

<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>


Icon 属性:图标

theme 属性:指定主题

Activity 之间的跳转

显式意图跳转

可以引用到那个类, 并且可以引用到那个类的字节码时可以使用。

一般用于自己程序的内部。显式跳转不可以跳转到其他程序的页面中。

隐式意图跳转

可以在当前程序跳转到另一个程序的页面

隐式跳转不需要引用到那个类,但是必须得知道那个界面的动作(action)和信息(category)。

使用Intent意图传递数据

Activity 之间通过Intent 进行通信。Intent 即意图,用于描述一个页面的信息,同时也是一个数据的载体。

案例 RP计算器

public class MainActivity extends Activity {

private EditText et_name;
private RadioGroup rg_group;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

et_name = (EditText) findViewById(R.id.et_name);
rg_group = (RadioGroup) findViewById(R.id.radioGroup1);

}

// 点击按钮 实现计算人品 跳转到ResultActivity页面
public void click(View v) {
// [1]获取用户名
String name = et_name.getText().toString().trim();
// [2] 判断一下name 是否为空
if (TextUtils.isEmpty(name)) {
Toast.makeText(getApplicationContext(), "亲 请输入姓名", 1).show();
return;
}
// [3]判断用户选择的性别
int radioButtonId = rg_group.getCheckedRadioButtonId();
int sex  = 0;

switch (radioButtonId) {
case R.id.rb_male: // 代表选择的是男

sex = 1;
break;

case R.id.rb_female: // 代表选择的是女

sex = 2;

break;

case R.id.rb_other: // 代表选择的是人妖

sex = 3;
break;

}
if(sex == 0){
Toast.makeText(getApplicationContext(), "请选择性别", 1).show();
return;
}

//[4]跳转到ResultActivity页面   用显示意图跳转
Intent intent = new Intent(this, ResultActiviyt.class);
//传递姓名
intent.putExtra("name", name);
//传递性别
intent.putExtra("sex", sex);

startActivity(intent);

}

}


跳转页

public class ResultActiviyt extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// [1]加载布局
setContentView(R.layout.activity_result);

TextView tv_name = (TextView) findViewById(R.id.tv_name);
TextView tv_sex = (TextView) findViewById(R.id.tv_sex);
TextView tv_result = (TextView) findViewById(R.id.tv_result);
// [2]获取mainActivity 传递过来的数据
Intent intent = getIntent(); // 获取开启此Activity的意图对象
// [3]获取name 和 sex 的值 小技巧 :传递的是什么数据类型 这边就按照传递的数据类型取
String name = intent.getStringExtra("name");
int sex = intent.getIntExtra("sex", 0);

// [4]根据name 和 sex 显示数据
tv_name.setText(name);

byte[] bytes = null;

// [5]显示性别
try {
switch (sex) {
case 1:

tv_sex.setText("男");
bytes = name.getBytes("gbk");

break;

case 2:
tv_sex.setText("女");
bytes = name.getBytes("utf-8");
break;

case 3:
tv_sex.setText("人妖");
bytes = name.getBytes("iso-8859-1");
break;

default:
break;
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
//[6]计算人品结果 市面上大多数应用采用的是随机数

int total = 0;
for (byte b : bytes) {                  // 0001 1111
int number = b&0xff;               // 1111 1111
total+=number;
}
// 获取得分
int score =  Math.abs(total)%100;
if (score > 90) {
tv_result.setText("您的人品非常好,您家的祖坟都冒青烟啦");
}else if (score > 80) {
tv_result.setText("您的人品还可以  ");
}else if (score > 60) {
tv_result.setText("您的人品刚及格");
}else{
tv_result.setText("您的人品太次了  您需要努力啊");

}

}

}


案例 短信发送器 (请求码,结果码)

requestCode 开启activity时设置的请求吗

resultCode 在目标activity中设置的结果码

主页面

public class MainActivity extends Activity {

private EditText et_number;
private EditText et_content;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//[1]找到我们关心的控件

et_number = (EditText) findViewById(R.id.et_number);
et_content = (EditText) findViewById(R.id.et_content);

}

//点击按钮跳转到发送短信模板页面
public void insertsms(View v){
Intent intent = new Intent(this,SmsTemplateActivity.class);
startActivityForResult(intent, 2);
}

//点击按钮 跳转到ContactActivity 页面
public void add(View v){
Intent intent = new Intent(this,ContactActivity.class);
//      startActivity(intent);
//小细节 如果点击按钮 开启了另外一Activity   并且当开启的这个Activity关闭的时候  我想要这个开启Activity的数据  用下面这个方法开启activity
startActivityForResult(intent, 1);
}

//当我们开启的Activity 页面关闭的时候 这个方法就调用
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (requestCode==1) {
//代表请求ContactActivity这个页面的数据
String phone = data.getStringExtra("phone");
et_number.setText(phone);

}else if (requestCode == 2) {
//代表请求 短信模板页面的数据

String smsContent = data.getStringExtra("smscontent");
et_content.setText(smsContent);
}

/*
if (resultCode == 10) {
//说明数据是从 ContactActivity 返回
String phone = data.getStringExtra("phone");
et_number.setText(phone);

}else if (resultCode == 20) {
//说明数据 是从 SmsTempate 返回
String smsContent = data.getStringExtra("smscontent");
et_content.setText(smsContent);
}
*/

super.onActivityResult(requestCode, resultCode, data);
}

//点击按钮 发送短信
public void send(View v){

//[1]获取发送短信的号码 和 发送的内容
String number = et_number.getText().toString().trim();
String content = et_content.getText().toString().trim();
//[2]获取到smsmanager的实例
SmsManager smsManager = SmsManager.getDefault();

ArrayList<String> divideMessages = smsManager.divideMessage(content);
for (String div : divideMessages) {

/**
* destinationAddress  发送给谁
* scAddress  服务中心号码
*
* text 要发送的内容
*/

smsManager.sendTextMessage(number, null, div, null, null);
}

}

}


获取联系人页面

public class ContactActivity extends Activity {

private List<Person> lists;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//加载布局
setContentView(R.layout.activity_contact);

//[1]找到控件
ListView lv = (ListView) findViewById(R.id.lv);

//[2]准备listview 要显示的数据  模拟点假数据
lists = new ArrayList<Person>();
for (int i = 0; i < 20; i++) {
Person p = new Person();
p.setName("张三"+i);
p.setPhone("11"+i);
lists.add(p);
}

//[3]展示数据
lv.setAdapter(new MyAdapter());

//[4]给listview 设置点击事件
lv.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {

//[5]获取我点中条目的数据   数据在哪里面存着呢 就去哪里取
String phone = lists.get(position).getPhone();

//[5.0]把数据返回给调用者
Intent intent = new Intent();
intent.putExtra("phone", phone);

//把结果返回给调用者
setResult(10, intent);

//[5.1]关闭当前页面
finish();
}
});
}

@Override
public void onBackPressed() {
super.onBackPressed();
}

private class MyAdapter extends BaseAdapter{

@Override
public int getCount() {
return lists.size();
}

@Override
public Object getItem(int position) {
return null;
}

@Override
public long getItemId(int position) {
return 0;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
if (convertView == null) {
view = View.inflate(getApplicationContext(), R.layout.contact_item, null);
}else {
view = convertView;

}
//[1]找到我们在item 中定义的控件   用来显示 数据
TextView tv_name = (TextView) view.findViewById(R.id.tv_name);
TextView tv_phone = (TextView) view.findViewById(R.id.tv_phone);
//[2]展示数据
tv_name.setText(lists.get(position).getName());
tv_phone.setText(lists.get(position).getPhone());
return view;
}

}
}


获取短信模板页

public class SmsTemplateActivity extends Activity {

String objects[] = {"我在吃饭,请稍后联系","我在开会,请稍后联系","我在上课,请稍后联系","我在打代码,请稍后联系","我在约会,请稍后联系"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_smstemplate);

//[1]找到lv
ListView lv = (ListView) findViewById(R.id.lv);

ArrayAdapter<String> adapter = new ArrayAdapter<String>(getApplicationContext(), R.layout.smstemplate_item, objects);

//[2]显示数据
lv.setAdapter(adapter);

//[3]设置lv 的条目的点击事件
lv.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {

//[4]取出点击条目的数据
String smsContent = objects[position];

//[5]把smsContent 返回调用者
Intent intent = new Intent();
intent.putExtra("smscontent", smsContent);
setResult(20, intent);

//[6]调用finish
finish();
}
});

}
}


Activity生命周期

Activity 有三种状态:

- 1、当它在屏幕前台时,响应用户操作的Activity, 它是激活或运行状态

- 2、当它上面有另外一个Activity,使它失去了焦点但仍然对用户可见时, 它处于暂停状态。

- 3、当它完全被另一个Activity 覆盖时则处于停止状态。

当Activity 从一种状态转变到另一种状态时,会调用以下保护方法来通知这种变化:

方法名说明
void onCreate()设置布局以及进行初始化操作
void onStart()可见, 但不可交互
void onRestart()调用onStart()
void onResume()可见, 可交互
void onPause()部分可见, 不可交互
void onStop()完全不可见
void onDestroy()销毁




startActivity 开启一个Activity 时, 生命周期的过程是:

onCreate ->onStart(可见不可交互) ->onResume(可见可交互)

点击back 键关闭一个Activity 时, 生命周期的过程是:

onPause(部分可见不可交互)->onStop(完全不可见)->onDestroy(销毁)

当开启一个新的Activity(以对话框形式), 新的activity 把后面的activity 给盖住一部分时, 后面的activity 的生命周期执行的方法是:

onPause(部分可见, 不可交互)

Activity 以对话框的形式显示,需在activity 节点追加主题android:theme=”@android:style/Theme.Dialog”

当把新开启的Activity(以对话框形式)给关闭时, 后面的activity 的生命周期执行的方法是:

onResume(可见, 可交互)

当开启一个新的activity 把后面的activity 完全盖住时, 生命周期的方法执行顺序是:

onPause ->onStop(完全不可见)

当把新开启的activity(完全盖住)给关闭时, 生命周期的方法执行顺序是:

onRestart ->onStart ->onResume(可见, 可交互)

实际工作中常用的方法以及应用场景有:

onResume 可见, 可交互.。把动态刷新的操作启动。

onPause 部分可见, 不可交互. 把动态刷新的一些操作, 给暂停了。

onCreate 初始化一些大量的数据。

onDestroy 把数据给释放掉, 节省内存。

横竖屏切换

横竖屏切换时,默认情况下会把activity 先销毁再创建,这个体验是非常差的

不让Activity 在横竖屏切换时销毁,只需要在清单文件声明Activity 时配置节点的几个属性即可

兼容所有版本:

android:configChanges="orientation|keyboardHidden|screenSize


禁止横竖屏:

screenOrientation=”” 指定屏幕固定方向,不会随着屏幕旋转而旋转

android:screenOrientation=”portrait” 始终竖屏

android:screenOrientation=”landscape” 始终横屏

Activity任务栈

程序打开时就创建了一个任务栈, 用于存储当前程序的activity,所有的activity 属于一个任务栈。

一个任务栈包含了一个activity 的集合, 去有序的选择哪一个activity 和用户进行交互:只有在任务栈栈顶的activity 才可以跟用户进行交互

任务栈可以移动到后台, 并且保留了每一个activity 的状态. 并且有序的给用户列出它们的任务, 而且还不丢失它们状态信息

退出应用程序时:当把所有的任务栈中所有的activity 清除出栈时,任务栈会被销毁,程序退出。

重复数据太多, 会导致内存溢出的问题(OOM)

Activity启动模式

为了解决任务栈产生的问题,Android 为Activity 设计了启动模式

可以在AndroidManifest.xml 配置的android:launchMode 属性为以下四种之一即可。

四种launchMode:

1.standard

默认模式

2.singleTop

如果任务栈的栈顶存在这个要开启的activity,不会重新的创建activity,而是复用已经存在的activity。保证栈顶如果存在,不会重复创建。

应用场景:浏览器的书签

3.singleTask

单一任务栈,在当前任务栈里面只能有一个实例存在,

当开启activity的时候,就去检查在任务栈里面是否有实例已经存在,

如果有实例存在就复用这个已经存在的activity,

并且把这个activity上面的所有的别的activity都清空,

复用这个已经存在的activity。保证整个任务栈里面只有一个实例存在

应用场景:浏览器的activity

4.singleInstance

activity会运行在自己的任务栈里面,并且这个任务栈里面只有一个实例存在

如果你要保证一个activity在整个手机操作系统里面只有一个实例存在,使用singleInstance

应用场景: 来电页面
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: