一,什么是Activity? 活动
Activity:一个单独的屏幕 一个显示的窗口 一个界面定义:用来显示android应用的界面的一个组件!!!
什么是android组件:
android应用:主要由4大组件构成
组件:创建 销毁 :一个组件从创建到销毁的过程:生命周期
不同的组件功能不同
android的四大组件:
Activity(界面)----接待
BroadCastReceiver(广播)---品牌
Service(服务)---做服务
ContentProvider(内容提供者)---真正提供具体服务
用户:服务
NOTO:anroid组件都必须在清单文件中注册
二,怎么样在清单文件中注册组件:
<activityandroid:name="com.tz.katehome.MainActivity" activity名字
android:label="@string/app_name" > activity的标签
</activity>
意图过滤器:找到组件
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
上面的代码作用:指定我们当前的android应用第1个启动的activity
三,Activity的生命周期
(官方文档 :1,翻墙软件 2,国内的镜像 3,sdk--dosc目录)
国内的镜像:http://wear.techbrood.com/guide/components/activities.html
onCreate,创建activity
onStart,可以看到activity
onResume,获取焦点,用户可以进行交互
onPause,失去焦点,被其他activity部分遮挡
onStop ,不可见activity
onDestroy, 销毁activity
onPause->onResume, 弹出的activity退出时,主activity会进入onResume方法
onStop->onRestart->onStart
四,Activity的启动方式:(启动模式)
(1)显示启动activity,只能启动当前应用activity
//一个activity启动另一个actiivty,只能在当前应用启动activity
//:Intent意图--四大组件的纽带
//参数:1,当前activity的context 2,启动得到Activity的.class//activity启动1
//Intent intent = new Intent(this,OtherActivity.class);
//activity启动2
Intent intent = new Intent();
//intent.setClassName(this,"com.tz.activitylifecycle.OtherActivity");
//activity启动3
//intent.setClassName(getPackageName(),"com.tz.activitylifecycle.OtherActivity");
//activity启动4
//intent.setClass(this, OtherActivity.class);
//activity启动5 Component :组织 组件
ComponentName component = new ComponentName(this, OtherActivity.class);
intent.setComponent(component);
(2)隐式启动 ,跨进程启动activity
意图过滤器---不同应用之间来启动Actvity(其他组件)
Intent是基于消息通讯机制
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
上面这的action和catetory是用来配置应用的第1个启动的Actvit的(可以配置多个,但是会启动xml中的第1个)
Intent-filter:包含两个部分
1,目的【action】--------要到哪里去2,内容【category,data】------去的路上要带什么,区分性数据和内容性数据
意图过滤器的配置:
1,action+category
总结:(1),所有的activity的过滤器都必须设置(但是第1个启动的activity不必)
<category android:name="android.intent.category.DEFAULT"/>
(2),在startActivity(Intent intent)方法内部默认设置了category的值为
android.intent.category.DEFAULT"
(3),(在没有设置数据)只要intent中action和category都出现在Intent-Filteer中就能与之匹配,
否者匹配失败
2,actoin+data
URI:统一资源标示 跟网址的组成部分是一样Uri: tzEdu://www.tanzhou.com/kate
uri格式:http://blog.csdn.net/sunny09290/article/details/7514963
URL:统一资源定位 http://www.baidu.com/index.html/3(网址)
http:// -----scheme 主题
www.baidu.com ---host 主机地址
index.html ----path 路径
3 -----id
总结:
1)如果在Intent-filter中制定了data,如果要匹配到此Activity,必须在
intent中设置data,否者匹配不到
2)Scheme属性没有指定,其他属性都无效,host没有指定 port path都无效
3 action+data+miniType
<data android:scheme="tzEdu" android:host="www.tanzhou.com"android:path="/kate" 注意path一定要加 //>
<data android:mimeType="image/*"/>
1)当有data和miniType同时存在,不要单独通过 setData() 和setType()方法进行设置
要通过setDataAndType()同时设置数据和类型才可以匹配
4 action + minaType
<data android:mimeType="image/*"/>intent.setType("image/png");
五,设置点击事件:
(1)xml布局中为要设置点击事件的控件加属性:android:onClick="startOther"
然后在activity中定义startOther(View v){}方法
在Activity获取控件对象,然后通过setOnClickListener(this);
Activity实现OnClickListener接口 然后重写接口的onClick方法
(3)匿名内部类监听器
start.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
}
});
(4)重写监听器类 实现OnClickListener接口
btn_start.setOnClickListener(new MyOnclicklistener());
public class MyOnclicklistener implements View.OnClickListener{
@Override
public void onClick(View v) {
}
}
(5)注解的方式(ioc)
六 activity模式
Activity一共有以下四种launchMode:
1.standard
2.singleTop
3.singleTask
4.singleInstance
作用概述:规定是否新建activity,是否公用task(task:应用启动时,会创建一个对应的task。task主要负责对activity进行管理。)
使用方法:我们可以在AndroidManifest.xml配置<activity>的android:launchMode属性为以上四种之一即可,默认情况下为标准模式。
第一种模式:standard
这是系统默认的启动模式,即:不用再在AndroidManifest.xml配置<activity>的android:launchMode。
作用:标准模式下,只要用intent 跳转,系统会自动创建一个新的activity实例,并且放在栈顶。按下回退键,系统会从顶部开始一个一个清除Activity。
第二种模式:singleTop
作用:singleTop模式下,如果要跳转的activity的实例已经在栈中存在,看其是否位于栈顶,如果位于栈顶,则直接启用旧的,不在创建实例,如果不在栈顶,则创建一个新的实例。
第三种模式:singleTask
作用:如果要启动的activity的实例不存在,则创建一个新的实例。如果要启动activity的实例在栈中已经存在,则清除此activty旧实例以上的所有activity,启动旧activity的实例并且至于栈顶,开始执行OnResum()方法。
问题:启动模式为singletask,activity无法获取到intent的传值问题。
原因:
1.启动一个为启动过的activity ,会获取到新的 intent。也就是说就是启动模式设置为:singletask,第一次启动界面是传递的数据是可以接受到的。
2.当此界面再次被启动时,因为他的启动模式是:singletask,所以不会重新创建一个activity,而是启动旧的activity实例,通过getIntent()方法获取到的 intent 也是旧的Intent,没有携带新的数据。所以无法获取到数据。
解决方法:重写这个方法,并且把调用setIntent(intent),对Intent进行更新。此方法在activity(启动模式为:singletask)的界面第二次启动时,在onresume()方法之前被回调。
@Override
protected void onNewIntent(Intent intent) {
// TODO Auto-generated method stub
super.onNewIntent(intent);
setIntent(intent);
}
第四种模式:singleInstance
作用:系统会重新启用一个栈,并且把这个activity放入新的栈中,并且保证不会再让其他的activity进入。再次跳转该activity,activity如果存在则直接启用,不存在创建新的。
注意:5.0以上的部分手机,一个应用存在多个栈的情况下,切到后台,后台会出现多个后台同一个应用的界面,这是因为界面不在同一个栈中。
七 Activity栈(Task)的相关知识总结:
1.Activity的affinity(亲和力)
2.Intent几种常见的flags
3.<activity>与task相关属性
第一个: Affinity(密切关系)
在系统默认情况下,打开一个app,系统默认包名为affinity的值。task自身的affinity的值取决于根activity的affinity。具有相同的affinity的activity同属于一个task。
实例1:
建立两个demo App分别命名为 A 和 B。从 A 的主界面通过意图跳转到 B 的主界面界面。此时两个app的界面位于同一个App A的栈内。如图:
第二个: Intent 常用的 flag:
1.FLAG_ACTIVITY_NEW_TASK 根据Activity 的 affinity去寻找task 栈。如果一个task 的 affinity与 activity 的 affinity的相同,则 Activity会压入栈中。如果没有找到相同的,则新建立栈,并且把activity压入栈中。
实例1: 从App A主界面跳转到 App B主界面。给Intent添加FLAG_ACTIVITY_NEW_TASK 标识。
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
结果会建立两个栈。App A 的界面在App A 的栈里。App B 的界面在 App B 的栈里边。
实例2:在实例1 的基础上,在App B里添加代码,给App B的主界面 在manifest 中添加
<activity
android:name="com.example.b.MainActivity"
android:taskAffinity="com.example.a"
android:label="@string/app_name" >
<intent-filter>
<action android:name="hello" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
com.example.a为App A 的包名。这样的结果是 App A 和App B的界面会在同一个栈里。
2.FLAG_ACTIVITY_CLEAR_TOP 检查栈内是否存在要启动的Activity实例,如果存在实例,则会调用旧的Activity实例,并且清除此Activty 上面的所有的activty,使其至于栈顶显示出来。
注意:1. intnet.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 跳转的页面会从 OnCreate()方法开始执行。
2.FLAG_ACTIVITY_CLEAR_TOP 相当于 加载模式的 signleTask
3.FLAG_ACTIVITY_SINGLE_TOP 相当于加载模式的 signleTop
4.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET 如果Intent 包含此属性,那么,要跳转的activity和次activity上的所有界面,都会在task重置时被清除。(待定)
5.FLAG_ACTIVITY_NO_HISTORY 如果Intent 包含此属性,那么,要启动activity 将显示一次,不会再task栈内保存。
6.FLAG_ACTIVITY_REORDER_TO_FRONT 把已经存在的界面拿到栈顶,
例:ABCD已经存在,D通过FLAG_ACTIVITY_REORDER_TO_FRONT 去启动A,则栈内顺序BCDA。
7.FLAG_ACTIVITY_BROUGHT_TO_FRONT(测试不起作用)
八,Activity之间数据的传递
Activity之间传数据* 1,基本类型和数组
* 2, 传对象 a,bundle对象(andoid写好的)
* b,自定义的对象:序列化 java中用:Serializable 不可以跨进程* android中用:Parcelable 可以跨进程
NOTE: parcelable序列化的时候,write属性的顺序必须和read的顺序一致
* android中推荐使用:Parcelable
自定义对象要implements Serializable 或者Parcelable
Serializable:简单,不需要实现方法,不跨进程
Parcelable:复杂,需要实现相关方法,且读写对象顺序要一致,跨进程
intent.putExtra("bitmap",bitmap);
Bitmap bitmap = intent.getParcelableExtra("bitmap");
Activity之间的回传数据
1,启动方式:
startActivityForResult(intent, 101);//请求码
2,返回方式:
setResult(100,intent);
finish();//销毁当前界面
3, 回传过来的数据会被 onActivityResult接收
通过请求码和结束码来区分不同请求和回传值
Intent intent = new Intent(this,SecondActivity.class);
/**
* 带数据
* 1,基本类型和数组
* 2, 传对象 a,bundle对象(andoid写好的)
* b,自定义的对象:序列化 java:Serializable 不可以跨进程
* android:Parcelable 可以跨进程
* android中推荐使用:Parcelable
*/
/*intent.putExtra("name", "二狗子");//key-value:键值对
intent.putExtra("age", 18);*/
/*Bundle bundle = new Bundle();//袋子
bundle.putString("name","二狗子");
bundle.putInt("age",18);
intent.putExtra("bundle", bundle);*/
/*Student stu = new Student();
stu.setName("二狗子");
stu.setAge(18);
intent.putExtra("stu", stu);//java序列化*/
/*Person p = new Person("旺财",12);
intent.putExtra("person", p);*/
Bitmap bitmap =BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
intent.putExtra("bitmap",bitmap);
startActivity(intent);
package com.example.kateintent_tz; import java.io.Serializable; public class Student implements Serializable{ private static final long serialVersionUID = 1L; private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }
package com.example.kateintent_tz; import android.os.Parcel; import android.os.Parcelable; /** * public class MyParcelable implements Parcelable { private int mData; public int describeContents() { return 0; } public void writeToParcel(Parcel out, int flags) { out.writeInt(mData); } public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() { public MyParcelable createFromParcel(Parcel in) { return new MyParcelable(in); } public MyParcelable[] newArray(int size) { return new MyParcelable[size]; } }; private MyParcelable(Parcel in) { mData = in.readInt(); } } * @author Administrator * */ public class Person implements Parcelable{ private String name; int age; public Person(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } public int describeContents() { return 0; } public void writeToParcel(Parcel out, int flags) { out.writeString(name); out.writeInt(age); } public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() { public Person createFromParcel(Parcel in) { return new Person(in); } public Person[] newArray(int size) { return new Person[size]; } }; private Person(Parcel in) { name = in.readString(); age = in.readInt(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
知识:手机中放入(视频 音频 图片 )多媒体文件,android系统会将多媒体文件信息保存到系统数据库中