活动(Activity)是一种可以包含用户界面的组件,主要用和用户进行交互。一个应用程序中可以包含零个或多个活动。
1.活动的基本用法
首先我们创建一个工程。命名为TestActivity。
然后一直点击下一步会到以下界面。
因为这个时候系统默认想要为我们创建一个命名为MainActivity的活动,并加载了布局activity_main.xml。我们不去更改它,建立完成之后进去看它的代码,我们就知道怎么回事了。(下面的代码为了让读者看到路径更好的理解活动,我将会放出图片)
这就是一个活动的代码部分,首先新建一个活动类并让其继承Activity,然后在其中重写onCreate()方法进行初始化,最后通过setContentView()来加载一个布局。
这就是我们所加载的布局,布局通常放在res下的layout文件包下。
当然,作为安卓的四大组件,活动想要正常使用自然是需要在AndroidManifest.xml中注册(11-17行代码)的。如果想要在程序启动时候首先跳转到该活动,就需要写入图中12-16行代码的声明。
然后是几个知识点:
A)隐藏标题栏,只需要在加载布局之前,写入requestWindowFeature(WINDOW.FEATRUE_NO_TITLE)即可。
B)Toast提醒方式,在程序中使用它可以将一些短小的信息提示给用户,这些信息存在一段时间后会自动消失。写入Toast.makeText(Context, " ", Toast.LENGTH_SHORT).show即可。这个方法实际上传入的是三个参数:第一个是上下文Context;第二个是想要显示的文本内容;第三个是显示的时间长,内置的常量除了我们写出的Toast.LENGTH_SHORT还有Toast.LENGTH_LONG。然后调用show()就可以将Toast显示在屏幕上了。
C)菜单的使用,由于手机使用情况跟电脑不同,它只有很小的一个屏幕,而且很有可能由于某种需求,我们的活动上必须显示大量的菜单列表,这时候为了避免占用屏幕我们可以采用菜单方式来实现。由于在编写软件的过程中我们可能涉及到大量的菜单,因此我们可以新建一个文件夹专门用来放菜单(就像布局那样)。所以在res下新建一个menu文件夹,然后在里面创建我们的第一个菜单布局。如下图所示:
然后我们需要在活动中去实现如下代码:
package company.testactivity; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @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.add_item: Toast.makeText(MainActivity.this, "Add Selected", Toast.LENGTH_SHORT).show(); break; case R.id.remove_item: Toast.makeText(MainActivity.this, "Remove Selected", Toast.LENGTH_LONG).show(); break; default: } return true; } }
首先通过重写构造方法onCreateOptionMenu()来创建菜单,通过getMenuInflater得到MenuInflater对象,在调用它的inflate方法就可以给当前活动创建菜单了。紧接着,我们为菜单定义一个点击事件,表示我们这个菜单不是“只可远观不可亵玩”的,同时应用了刚才所提到的Toast方法。
D)销毁一个活动。想要通过代码销毁一个活动时,只需要写入finish()方法即可。
2.Intent在活动中的使用
Intent为意图的意思,这很形象的描述了它的作用,而它主要分为显式和隐式两种。
我们先来看显式Intent。
首先新建一个活动,并加载一个布局,前面已经讲述过方法了,记得注册就好,不再赘述。重点来看主活动中的代码:
package company.testactivity; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button mButton = (Button) findViewById(R.id.explicit_intent); mButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String data = "this is a extra information from MainActivity"; Intent explicitIntent = new Intent(MainActivity.this, AnotherActivity.class); explicitIntent.putExtra("extra data", data); startActivity(explicitIntent); } }); } . . . }
我们增添了一个按钮,然后为其设置了一个点击事件。在点击逻辑中写入了Intent相关的东西。首先new一个explicitIntent实例,里面传入两个参数:当前活动和目标活动。通过startActivity(explicitIntent)方法即可实现由一个活动跳转到另一个活动的操作。只不过我们这里一并演示了跳转过程中携带信息,这是Intent很重要的一个功能。通过putExtra()方法来实现,传入两个参数:信息的名称和信息的内容。
package company.testactivity; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.Toast; /** * Created by samyang on 2016/9/12. */ public class AnotherActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.another_activity); Intent intent = getIntent(); String data = intent.getStringExtra("extra data"); Toast.makeText(AnotherActivity.this, data, Toast.LENGTH_LONG).show(); } }
然而目标活动想要接收传过来的信息需要调用getIntent()方法来获取从第一个活动传过来的意图实例,然后利用该实例调用getStringExtra()方法并传入信息名称来拿到信息,这里我们还是通过Toast作一个简单的演示。
这里简单提一下,布局都很简单,左边是放了一个TextView,下面放了一个Button;右边仅放了一个TextView。代码就不放出来了,接下来的简单部分亦是。
接下来看隐式Intent
隐式Intent并不直接指定想要跳转的活动,而是指定一系列更为抽象的<action>及<category>信息,然后交给系统去分析这个intent从而判断想要启动的活动。我在在<action>标签中指定活动可以响应的action,而<category>则包含了一些附加信息,用于更精确的匹配响应。只有<action>及<category>能够同时匹配Intent中指定的action及category时这个活动才能响应Intent。核心代码为:
<activity android:name=".ThirdActivity"> <intent-filter> <action android:name="company.testactivity.ACTION_START"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.MY_CATEGORY"/> </intent-filter> </activity>
点击新加入的按钮之后跳转到ThirdActivity如下图所示:Button maButton = (Button) findViewById(R.id.implicit_intent); maButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent implicitIntent = new Intent("company.testactivity.ACTION_START"); implicitIntent.addCategory("android.intent.category.MY_CATEGORY"); startActivity(implicitIntent); } });
除此之外,隐式的Intent还有更多用处。例如:可以启动其它程序的活动,这使得Android中的多个软件共享成为了可能。
返回数据
Button mButton = (Button) findViewById(R.id.explicit_intent); mButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String data = "this is a extra information from MainActivity"; Intent explicitIntent = new Intent(MainActivity.this, AnotherActivity.class); explicitIntent.putExtra("extra data", data); startActivityForResult(explicitIntent, 1); } });
Button backButton = (Button) findViewById(R.id.back_button); backButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent1 = new Intent(); intent1.putExtra("data return", "Hello MainActivity"); setResult(RESULT_OK, intent1); finish(); } });
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case 1: if (resultCode == RESULT_OK){ String returnedData = data.getStringExtra("data return"); Toast.makeText(MainActivity.this, returnedData, Toast.LENGTH_SHORT).show(); } break; default: } }
3.活动的生命周期
而关于活动的生命周期,我们需要知道,每个活动在其生命周期内最多可能会有四种状态:
a)运行状态:当一个活动处于返回栈的栈顶时,就处于运行状态,这种状态的活动是系统最不愿意回收,因为这会带来极差的用户体验。
b)暂停状态:当一个活动不再处于栈顶但仍然可见时就会进入这种状态。处于暂停状态的活动仍然是完全存活的,系统也不愿意回收这样的活动,只有在内存极低的时候才会考虑去回收这样的活动。
c)停止状态:当一个活动不再处于栈顶位置,并且完全不可见,就进入了停止状态。此时系统仍然为这种活动保留了成员变量,但是当其他地方需要更多内存时就会回收这种活动,所以这种状态下保存的数据并不可靠。
d)销毁状态:当一个活动从返回栈中移除了之后就变成这种状态,系统最愿意回收这种状态的活动。
而生命周期的七种回调方法在理解上述四种状态之后再结合下图就可以很好的理解了。
4.活动被回收了怎么办
@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); String tempData = "Something you want to save"; outState.putString("data key", tempData); }