1、什么是Activity?Activity和Window、View的区别是什么?
Activity是和用户交互的界面,即我们看得见的最大的那部分。Window是窗口,负责承载View,每个Activity对应一个Window,Window下有一个ViewRoot,可以通过这个ViewRoot添加View。View是视图,用于显示各种组件和布局。
2、Activity中如何隐藏上方的标题栏和状态栏?
有两种方法,一种是在代码中修改。
//去除标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
//去除状态栏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
第二种是在配置文件里修改
<!--去掉标题栏-->
android:theme="@android:style/Theme.NoTitleBar"
<!--去掉状态栏-->
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
3、给Activity添加菜单
(1)、在res目录下新建一个menu文件夹,在文件夹下新建.XML文件,设置菜单的布局。如:menu_login.xml
<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=".LoginActivity">
<item android:id="@+id/action_settings" android:title="@string/action_settings"
android:orderInCategory="100" app:showAsAction="never" />
<item android:id="@+id/add"
android:title="增加"></item>
</menu>
(2)、重写Activity的onCreateOptionsMenu(Menu menu)方法,将菜单的布局加载进去
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
}
(3)、在Activity的onOptionsItemSelected(MenuItem item)中判断按下的菜单键并编写相应的处理
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
if(id == R.id.add){
Toast.makeText(this,"你点击了增加菜单",Toast.LENGTH_SHORT).show();
}
return true;
}
4、什么是Intent,如何通过Intent启动一个活动?
Intent主要是解决Android应用的各项组件之间的通讯,负责对应用中的一次操作的动作以及动作涉及的数据、附加数据进行描述,系统通过此描述找到相应的组件,并将Intent对象传递给组件,完成组件的调用。Intent实际起到一个中介的作用,专门提供组件互相调用的信息,实现调用者与被调用者之间的解藕。Intent一般用于启动活动、启动服务、以及发送广播。
通过Intent启动一个活动有两种方式:显式Intent和隐式Intent.
显式Intent比较简单,直接传递当前上下文以及要启动的类名给Intent即可。Intent还可以携带数据给被启动的组件。
Intent intent = new Intent(this,MyService.class);
intent.putExtra("extraData","nihao");
startActivity(intent);
启动另一个活动后,使用getIntent()方法即可获得带有数据的intent.
隐式Intent不明确指定我们要启动的活动,而是通过设置动作让相应的活动来响应。可以在AndroidManifest.xml中设置活动响应的动作。
<activity android:name=".MyService">
<intent-filter>
<action android:name="com.mhwang.activity.MYSERVICE"></action>
</intent-filter>
</activity>
然后在需要启动时设置Intent的动作
Intent intent = new Intent("com.mhwang.activity.Service");
startActivity(intent);
5、如何在活动之间传递数据
其实在活动之间传递数据很简单,在Intent中提供了一系列putExtra()方法的重载,可以把我们想要传递的数据暂时存在Intent中,通过Intent启动另一个活动后,只要在新
启动的活动中获得Intent对象,然后通过Intent的getExtra()就可以获得数据。
Intent intent = new Intent(this,SecondActivity.class);
intent.putExtra("data","this is data");
startActivity(intent);
在SecondActivity中取出数据:
Intent intent = getIntent();
String data = intent.getStringExtra("data");
6、如何理解活动的生命周期?
一个Activity的启动顺序为:onCreate-->onStart()-->onResume();
当需要启动另一个Activity时:
如果新Activity不是全屏覆盖或者是透明的:旧Activity:-->onPause(),然后新启动的Activity:-->onCreate()-->onStart()-->onResume();
当新Activity销毁时执行:onPause()-->onStop()-->onDestroy(); 然后旧Activity:-->onResume();
如果新Activity是全屏覆盖的:旧Activity:-->onPause()-->onStop();然后新启动的Activity:-->-->onCreate()-->onStart()-->onResume();
当新Activity销毁时执行:onPause()-->onStop()-->onDestroy(); 然后旧Activity:-->onRestart()-->onStart()-->onResume();
确切的说,Activity也可以分为三个生存周期:
(1)、完整期:
Activity在onCreate()方法到onDestroy()方法之间所经历的,就是完整的生存周期。Activity经历了从创建到销毁,Activity在onCreate()方法中完成各种初始化操作,在
onDestroy()方法中完成释放内存的操作。
(2)、存在期:
Activity在onStart()方法到onStop()方法之间所经历的。在此期间,Activity总是存在的,即使有时候不可见,即使有时候不能和用户进行交互。我们可以在onStart()中进行资源的加载,在onPause()中进行数据的保存,在onStop()中对资源释放,从而保证处于停止状态的Activity不会占用过多的内存。
(3)、前台期:
Activity在onStart()方法到onPause()方法之间所经历的。在此期间,Activity一直在运行,且可见的。此时的Activity可以和用户交互,我们平时看到的和接触最多的也是这个时期的Activity.
需要注意的是:如果系统内存不足回收Activity时,有可能是不执行onStop()而直接销毁活动的,所以如果需要保存数据应该在onPause中保存。
懂得了活动的状态发生改变顺序,当活动状态发生改变时,我们可以重写这些方法,实现一些逻辑。
7、Activity是通过什么管理的?Activity的启动方式有哪几种?
Activity是通过栈来管理的,栈是一种后进先出的数据结构,在Android启动模式默认的情况下,我们每启动的一个Activity都会入栈并处于栈顶位置,当要返回Activity的时候,当前显示给用户的Activity会出栈并销毁,下一个显示给用户的Activity处于栈顶。
Activity的启动方式有四种:
(1)、standard:这是Activity默认的启动模式,在没有标明启动模式的状态下,所有的Activity都启用这种模式,特点是:每启动一个Activity,都会将它压入栈,并处于栈顶的位置,不管栈中是否还有这个Activity,都将创建新的Activity入栈。
(2)、singleTop:每启动一个Activity,系统都会检查栈顶的是Activity是不是该Activity,如果是,则不创建新的Activity,而是重用栈顶的Activity,如果不是,则创建新的Activity并将它压入栈顶。
(3)、singleTask:每启动一个Activity,系统都会检查整个栈中是否有该Activity,如果有,则重用该Activity,并且处于该Activity上的所有Activity都将出栈,以便让该Activity处于栈顶,如果没有,则创建新的Activity并处于栈顶。
(4)、singleInstance:不同于前面三种,模式为singleInstance的Activity会新创建一个栈并将该Activity压入栈中,并且不会让其他Activity进入到该栈中。该模式常用于程序之间共享Activity。
8、如何方便的退出应用?
对于只有一个Activity的应用来说,直接在Activity中finish()或者killProcess()或者System.exit()就可以了,但是对于多个Activity来说,当打开了多个Activity,如果需要在最后的Activity直接退出就需要一个一个的退出,这样相当麻烦。网上有几种方法可以方便的退出:
(1)、抛出异常强制使程序结束
通过抛出异常,使程序Force Close结束应用,但是这种方法用户体验不好,需要改进。
(2)、发送特定广播
通过广播,让每个Activity收到后调用finish()结束。
(3)、递归退出
在打开新的Activity时使用startActivittyForResult,,然后自己加标志,在onActivityResult中递归关闭。
(4)、使用基类,收集每次打开的Activity,然后用for循环退出每个Activity
比较推荐的做法是使用基类,这样可以比较方便的管理打开的Activity。代码如下所示:
首先创建一个专门收集Activity的工具类ActivityCollector来管理Activity,实现对Activity的增、删、及清空
/**
* Created by mhwang on 2015/10/7.
*/
public class ActivityCollector extends Activity {
//创建收集Activity的容器
public static List<Activity> activities = new ArrayList<Activity>();
//添加Activity
public static void addActivity(Activity activity){
activities.add(activity);
}
//删除Activity
public static void removeActivity(Activity activity){
activities.remove(activity);
}
//清除所有Activity
public static void clearActivity(){
for(Activity a : activities){
if(!a.isFinishing())
a.finish();
}
}
}
接着创建基类BaseActivity,让所有的Activity都继承基类,在基类中对出现的每个Activity进行添加和删除
public class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityCollector.addActivity(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);
}
}
然后就可以在继承BaseActivity的Activity中方便的对所有Activity进行操作了
public class MainActivity extends BaseActivity {
Button btn_quick;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_quick = (Button)findViewById(R.id.quick);
btn_quick.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityCollector.clearActivity();
}
});
}