安卓初识之activity
我记得两年前就买了第一行代码这本书,当时打算学android开发的,不知道怎么回事就放弃了,大学期间真的是想到什么做什么,根本没有系统的学一样东西,虽然说python,php,java,c++,都学过,但又是什么都不会,就只会一些基础的东西,想想不能这样荒废,真的需要扎扎实实的掌握一门东西,在准备考研,也想在这个过程中学点其他的东西,扎扎实实,于是认真的写博客、总结,不为给别人看,就为总结给自己。
什么是activity?
Activity是Android一个非常重要的用户接口(四大组件之一),是可见的,主要是用户和应用程序之间进行交互的接口。在每个Activity中都可以放很多控件,所以也可以把Activity看作控件的容器。
个人理解就是HTML中的body,用来放元素的标签,比如div,p,等等,对应到android中就是各种View,例如TextView,button
Activity基本认识
创建Activity
我们创建的activity都继承于Activity或者是其子类。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("Tag","oncreate");
Log.d("Tag",this.toString());
setContentView(R.layout.activity_main);
}
}
如上即是一个完整的activity
从Activity中打开另一个Activity
利用Intent,可打开另外的Activity,其中Intent又分为显式与隐式。工程中有两个Activity,分别为MainActivity与SecondActivity。
显式打开Activity
在Activity A中加入一个Button,然后在onCreate中加入监听Button的Click事件的代码。
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivity(intent);
}
});
此时运行程序点击Button,即可打开第二个Activity。
以上为显式打开Activity,如何隐式打开Activity呢?
隐式打开Activity
指定action & category
我们在AndroidManifest文件中注册Intent-Filter,给SecondActivity分配action以及category属性,即指定SecondActivity可以相应什么样的隐式Intent,例如:
<Intent-filter>
<action android:name="com.it592.test.SecondActivity.ACTION_START"/>
<category android:name="android.intent.category.DEFAULT"/>
</Intent-filter>
其中指定SecondActivity是默认的category,在隐式调用的时候可不指定该参数,
此时隐式调用的方式即:
Intent intent = new Intent("com.it592.test.SecondActivity.ACTION_START");
startActivity(intent);
由于未指定Activity,其会默认调用category = android.intent.category.DEFAULT,在隐式调用中,我们只能指定一个action,但可以指定多个category,可以使用intent.addCategory添加category。
基于协议的隐式打开
在声明Intent时,我们指定action为系统默认的Intent.ACTION_VIEW,其常量值是android.intent.action.View,然后使用intent.setData()指定当前Intent正在操作的对象,并且传入一个Uri对象,在androidManifest文件中可以指定当前Activity可以处理的数据类型。
<Intent-filter>
<data android:scheme="http" //指定协议
</Intent-filter>
Activity传参
在网站的开发中,传参一般是使用POST以及get进行,当然在打开Activity的过程中,我们无法避免需要传参,我们可以把数据先暂存在Intent中,然后到了另外的获得中,再取出相应的数据。
传参
//传入参数
String data = "this is a data";
Intent intent = new Intent(*,*);
intent.putExtra("data",data);
startActivity(intent);
//取出参数
Intent intent = getIntent();
String data = intent.getStringExtra("data");
/*
String-> getStringExtra
Int-> getIntExtra
Boolean->getBooleanExtra
依次类推
*/
返回参数
返回参数依旧需要使用Intent,但是该Intent仅仅是用于传参,并没有其他的用途。
Intent intent = new Intent();
Intent.putExtra(*,*);
setResult(RESULT_OK,intent);
finish();//销毁当前的Activity
Activity的生命周期
Activity 基本上以三种状态存在:
已继续
此 Activity 位于屏幕前台并具有用户焦点。(有时也将此状态称作“运行中”。)
已暂停
另一个 Activity 位于屏幕前台并具有用户焦点,但此 Activity 仍可见。也就是说,另一个 Activity 显示在此 Activity 上方,并且该 Activity 部分透明或未覆盖整个屏幕。 已暂停的 Activity 处于完全 Activity 状态(Activity 对象保留在内存中,它保留了所有状态和成员信息,并与窗口管理器保持连接),但在内存极度不足的情况下,可能会被系统终止。
已停止
该 Activity 被另一个 Activity 完全遮盖(该 Activity 目前位于“后台”)。 已停止的 Activity 同样仍处于 Activity 状态(Activity 对象保留在内存中,它保留了所有状态和成员信息,但未与窗口管理器连接)。 不过,它对用户不再可见,在他处需要内存时可能会被系统终止。
考虑如下代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("Tag","oncreate");
setContentView(R.layout.activity_main);
View button = (Button)findViewById(R.id.button);
View button1 = (Button)findViewById(R.id.button2);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,Normal.class);
startActivity(intent);
}
});
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,Dialog.class);
startActivity(intent);
}
});
}
@Override
protected void onStart() {
/*可见状态*/
super.onStart();
Log.d("Tag","onstart");
}
@Override
protected void onResume() {
//可交互,在可见的前提下
super.onResume();
Log.d("Tag","onResume");
}
@Override
protected void onPause() {
//不可交互,但可能可见
super.onPause();
Log.d("Tag","onpause");
}
@Override
protected void onStop() {
//不可见
super.onStop();
Log.d("Tag","onStop");
}
@Override
protected void onRestart() {
//恢复可见
super.onRestart();
Log.d("Tag","OnRestart");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("Tag","ondestroy");
}
}
其中Normal.class是一个普通的Activity,Dialog.class是一个dialog类型的Activity(不会全占窗口),输出的日志如下:
//创建过程
09-22 23:59:12.318 27231-27231/com.it592.activity D/Tag: oncreate
09-22 23:59:12.408 27231-27231/com.it592.activity D/Tag: onstart
09-22 23:59:12.408 27231-27231/com.it592.activity D/Tag: onResume
//打开Normal
409-22 23:59:18.978 27231-27231/com.it592.activity D/Tag: onpause
09-22 23:59:19.148 27231-27231/com.it592.activity D/Tag: onStop
//关闭normal
09-22 23:59:26.508 27231-27231/com.it592.activity D/Tag: OnRestart
09-22 23:59:26.508 27231-27231/com.it592.activity D/Tag: onstart
09-22 23:59:26.508 27231-27231/com.it592.activity D/Tag: onResume
//打开dialog
09-22 23:59:37.388 27231-27231/com.it592.activity D/Tag: onpause
//关闭dialog
09-22 23:59:41.228 27231-27231/com.it592.activity D/Tag: onResume
在这个过程中,有三种状态,
1. 不可见
2. 可见不可交互
3. 可交互
1->2 调用onStart()/2->1调用onStop
2->3 调用onResume/3->2调用onPause
他们之间只能相互转换,但是不能跳跃,因此要想交互就必须先可见,要想不可见,就必须先到状态2。
活动的四种启动模式
standard、singleTop、singleTask、singleInstance