本篇内容整理自郭霖的 《第一行代码》
@id/id_xxx
@+id/id_xxx
match_parent
表示让当前元素和父元素一样match_content
表示当前元素刚好包含里面内容就好setContentView()
方法给活动加载一个布局 <application>
<activity
android:name=".FirstActivity"
android:label="This is FirstActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
intent-filter>
activity>
application>
android:label
不仅仅会成为标题栏的内容,还会成为启动器(LAUNCHER)中应用程序显示的名称。
android.intent.action.MAIN
是主活动,点击图标首先打开的就是此活动
requestWindowFeature(Window.FEATURE_NO_TITLE);
此句代码必须在 setContentView()
之前执行,否则报错
public void onClick(){
Toast.makeText(FirstActivity.this,"point out",Toast.LENGTH_SHORT).show();
}
通过静态方法makeText()创建出Toast对象,然后调用show()将Toast显示出来就好了。
makeText()
三个参数:
第一个:Context :Toast要求的上下文本
第二个: Toast显示的文本内容
第三个: 显示的时长:Toast.LENGTH_SHORT 和 Toast.LENGTH_LONG
1、在main.xml文件中添加代码
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/add_item"
android:title="Add" />
<item
android:id="@+id/remove_item"
android:title="Remove" />
menu>
2、重写Activity中的 onCreateOptionsMenus()
方法
public boolean onCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
inflate()两个参数:
第一个: 来创建菜单的资源文件
第二个:onCreateOptionsMenus()
方法中传入的menu
4. 对xml文件里面的item设置点击事件
finish()
方法eg:跳转另一个活动
public void onClick(){
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent); //专门启动活动的方法
}
<activity android:name=".SecondActivity"
>
<action android:name="com.package.name.ACTION_START" />
<category android:name="android.intent.category.DEFAULT" /> <--此为默认-->
<category android:name="com.package.name.MY_CATEGORY" />
intent-filter>
activity>
和
同时匹配上 Intent
中指定的 action 和 category 时,这个活动才能响应 Intentpublic void onClick(){
Intent intent = new Intent("com.package.name.ACTION_START");
intent.addCategory("com.package.name.MY_CATEGORY");
startActivity(intent); //此方法会自动将默认的category添加进intent中
}
//每一个Intent中只能指定一个action,但能指定多个category
使用隐式Intent, 不但可以启动自己程序内的活动,还能启动其他应用程序的活动。因此 Android 多个应用之间的功能共享成为可能
例1:
自己的应用需要打开网页,可调用系统的浏览器。在 FirstActivity 中代码实现如下:
public void onClick(){
Intent intent = new Intent(Intent.ACTION_VIEW); // intent构造方法所传入的参数为Android 系统内置的动作,其常量为android.intent.action.VIEW
intent.setData(Uri.parse("http://www.baidu.com")); // Uri.parse()将网址解析为一个Uri对象
//setData()方法接收uri对象,用于指定当前Intent正在操作的数据
startActivity(intent);
}
标签配置一个
标签,用于更精准地指定当前活动能够响应什么类型的数据。
标签可配置如下内容:
android : scheme 用于指定数据的协议部分,如上例中 http 部分
android : host 用于指定数据的主机部分,如上例中的 www.baidu.com 部分
android : path 用于指定主机名和端口之后的部分,如一段网址中跟在域名之后的内容
android : mimeType 用于指定可以处理的数据类型,允许使用通配符的方式进行指定
只有当前 标签中指定的内容和 Intent 中携带的 Data 完全一致的时,当前活动才能响应该 Intent
eg:新建个 ThirdActivity ,在 AndroidManifest 中对它进行注册
<activity android:name=".ThirdActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" /> <--data标签中指定了数据协议必须是http协议,这样ThirdActivity应该就和浏览器一样能够响应一个打开网页的Intent-->
intent-filter>
activity>
如此一来,执行 FirstActivity 的 onClick() 方法就不单单打开一个系统的浏览器去显示网页。而是跳出弹窗,让用户选择运用什么activity来执行这个intent:系统浏览器 or ThirdActivity ?因为系统浏览器和 ThirdActivity 都含有scheme=“http”,它们都可以响应这个打开网页的 Intent
简单理解:FirstActivity 中 intent 发出 http 协议,被含有scheme=“http”的活动响应
例2:
除了指定 http 协议外,我们还可以指定很多其他协议,比如 geo 表示显示地理位置、 tel 表示 拨打电话
public void onClick(){
Intent intent = new Intent(Intent.ACTION_DIAL); // 指定了intent 为 Intent.ACTION_DIAL 这又是一个 Android 系统内置动作
intent.setData(Uri.parse("tel:10086")); // 然后 data 部分指定了协议是 tel
startActivity(intent);
}
执行这个onClick(),拨号页面这个 Activity 就响应了tel,因此打开拨号窗口
存数据:intent.putExtra("key", data);
putExtra()
接收的两个参数
第一个:键
第二个:传递的数据
取数据:
Intent intent = getIntent(); //获取用于启动本活动的 Intent
String data = intent.getStringExtra("key");
//通过键获取数据,除了 getStringExtra() 外,还有 getIntExtra()、getBooleanExtra();通过传入的数据决定使用哪个
startActivityForResult()
**方法也是用于启动活动的,但它在启动的活动被销毁后会返回一个结果给上一个活动例:
FirstActivity
public void onClick(){
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivityForResult(intent, 1); // 第二个参数为请求码 requestCode ,用于在之后的回调中判断数据的来源
}
SecondActivity
public void onClick(){
Intent intent = new Intent();
intent.putExtra("key", "你好!");
setResult(RESULT_OK, intent); // 专门用于向上一个活动返回数据的,有两参数。第一个:向上一个活动返回处理结果; 第二个:把带参数的 intent 传过去
finish();
}
或者使用 onBackPressed()
方法,此方法在点击 Back 键后调用。因 Back 键也是销毁活动的,因此在最好也在此方法中添加活动被销毁前要返回的数据
FirstActivity
由于是用 startActivityForResult() 启动 SecondActivity 的,所以在 SecondActivity 被销毁后会回调上一个活动的 onActivityResult() 方法
protected void onActivityResult(int requestCode, int resultCoded, Intent data){
switch(requestCode){
case 1: // 请求码,判断数据是否从 SecondActivity 中来的
if(resultCode == RESULT_OK){ // 判断处理结果是否成功
String returnedData = data.getStringExtra("key");
}
break;
default:
}
}
运行状态:活动处于栈顶,系统最不愿回收
暂停状态:活动不处于栈顶,仍然可见(不占满屏幕的活动,比如对话框的形式出现)
停止状态:活动不处于栈顶,完全不可见(活动保留相应状态和成员变量,其他地方需要内存即刻回收)
销毁状态:活动从栈中移走
onResume():准备好与用户进行交互的时候调用(处于运行状态)
onPause():系统准备去启动或者恢复另一个活动的时候调用
onSaveInstanceState()
回调方法在活动被回收之前调用,可解决活动被回收,数据得不到保存的问题。onSaveInstanceState()
方法携带一个 Bundle 参数,此参数提供一系列的方法来保存数据:puString()、putInt() 等。每一个方法含有两个参数,类似 Intent 传递数据所采用的存放数据的方法。第一个:键;第二个:dataonCreate()
方法一直都有 Bundle 类型的参数,默认为 null ,如果 onSaveInstanceState()
中保存了数据,那么 Bundle 中就存在活动被销毁前的数据简单理解:Bundle 类型的参数在
onSaveInstanceState()
和onCreate()
中是共享的,前一个在活动销毁前存数据,后一个在活动开始前取数据
标签指定 android:launchMode
属性来选择启动模式。默认的启动模式。使用此模式,系统不会在乎这个活动是否已经在返回栈中,每次启动都会创建该活动的一个新的实例
使用此模式。在启动活动时如果发现返回栈的栈顶已经是该活动(前提),则认为可以直接使用它,不会再创建新的活动实例
使用此模式。每次启动该活动时系统首先会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这个活动之上的活动统统出栈,如果没有发现就会创建一个新的活动实例。
使用此模式启动的活动,会有一个单独的返回栈来管理这个活动,不管是哪个应用程序来访问这个活动,(这个活动)都共用的同一个返回栈。可以解决共享活动实例的问题(即允许其他程序来调用这个活动)
1、 新建一个 BaseActivity 继承 Activity
2、 在 BaseActivity 中重写 onCreate() 方法:
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
log.d("BaseActivity", getClass().getSimpleName()); // getClass().getSimpleName() 方法就是获取当前活动的类名
}
3、让所有活动都继承BaseActivity
1、新建一个 ActivityCollector 类作为活动管理器
public class ActivitykCollector{
public static List<Activity> activities = new ArrayList<Activity>();
public static void addActivity(Activity activity){
activities.add(activity);
}
public static void removeActivity(Activity activity){
activities.remove(activity);
}
public static void finishAll(){
for(Activity activity : activities){
activity.finish();
}
}
}
2、修改 BaseActivity(如何知晓当前是哪一个活动中的)代码
public class BaseActivity extends Activity{
protected void onCreated(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
ActivityCollector.addActivity(this);
}
protected void onDestroy(){
super.onDestroy();
ActivityCollector.removeActivity(this);
}
}
3、只要所有活动在继承 BaseActivity 基础上,不管什么地方退出程序只需要调用 ActivityCollector.finishAll()
SecondActivity
public class SecondActivity extends BaseActivity{
public static void actionStart(Context context, String data_1, String data_2){
Intent intent = new Intent(context, SecondActivity.class);
intent.putExtra("param_1", data_1);
intent.putExtra("param_2", data_2);
context.startActivity(intent);
} // 启动本活动的函数。这样处理,其他活动启动本活动的时候就可以把必要的参数也带进来
}
FirstActivity
public void onClick(){
SecondActivity.actionStart(FirstActivity.this, "data_1", "data_2");
} // 启动 SecondActivity 活动