Log.v(String tag,String msg);//verbose级别,最琐碎
Log.d(String tag,String msg);//debug级别,调试程序分析问题
Log.i(String tag,String msg);//info级别,帮助分析用户行为
Log.w(String tag,String msg);//warn级别,警告信息
Log.e(String tag,String msg);//error级别,打印错误信息
下面给出本书后面的自定义日志工具类,方便开发调试使用打印日志和发布打包的时候屏蔽日志
import android.util.Log;
public class LogUtil {
public static final int VERBOSE=1;
public static final int DEBUG=2;
public static final int INFO=3;
public static final int WARN=4;
public static final int ERROR=5;
public static final int NOTHING=6;
public static final int LEVEL=VERBOSE;
//LEVEL设置为VERBOSE表示级别最高,此工具类会打印所有信息,设置成NOTHING,此工具类不会打印任何日志
public static void v(String tag,String msg){
if (LEVEL<=VERBOSE){
Log.v(tag,msg);
}
}
public static void d(String tag,String msg){
if (LEVEL<=DEBUG){
Log.d(tag,msg);
}
}
public static void i(String tag,String msg){
if (LEVEL<=INFO){
Log.i(tag,msg);
}
}
public static void w(String tag,String msg){
if (LEVEL<=WARN){
Log.w(tag,msg);
}
}
public static void e(String tag,String msg){
if (LEVEL<=ERROR){
Log.e(tag,msg);
}
}
}
创建:1.新建一个布局文件(xml)
2.新建一个.java文件,自定义类继承自Activity,重写onCreate()函数
public class BaseActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//隐藏活动标题栏
requestWindowFeature(Window.FEATURE_NO_TITLE);
//Log.d("BaseActivity", getClass().getSimpleName());
setContentView(R.layout.first_layout);
}
最后别忘了注册哦,在AndroidManifest文件的< application >标签内注册activity
<activity android:name=".FirstActivity" android:launchMode="singleTask" android:label="This is FirstActivity!">
<intent-filter>//若这是一个主活动,需要这样写
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
1.在res文件夹中创建一个menu文件夹→创建Android XML File
→在activity中重写onCreateOptionsMenu(Menu menu)
→重写public boolean onOptionsItemSelected(MenuItem item)编写响应菜单项代码
Android XML File:
<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>
activity.java:
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.add_item:
Toast.makeText(FirstActivity.this, "you clicked Add", Toast.LENGTH_SHORT).show();
break;
case R.id.remove_item:
Toast.makeText(FirstActivity.this, "you clicked Remove", Toast.LENGTH_SHORT).show();
default:
break;
}
return true;
}
显式Intent:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
隐式Intent:
含蓄的Intent需要指定一系列action和category等信息,只有AndroidManifest的< activity>中< action>和< category>与intent的action和category完全匹配才能启动该activity。
<action android:name="com.example.activitytest.ACTION_START"/>
<category android:name="com.example.activitytest.MY_CATEGORY"/>
Intent intent=new Intent("com.example.activitytest.ACTION_START"); intent.addCategory("com.example.activitytest.MY_CATEGORY");
隐式intent还可以用来启动其他程序的活动
在< intent-filter>标签中在配置一个< data>标签
Intent intent1=new Intent(Intent.ACTION_VIEW);
intent1.setData(Uri.parse("http://www.baidu.com"));
//<data android:scheme="http"/> 在AndroidManifest中配置
Intent intent=new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
////<data android:scheme="tel"/>
startActivity(intent1);
1、可以通过intent.putExtra(String keyname, String value) 把数据暂存到intent中,启动到另一个活动后,再把数据通过键值从intent中取出。
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
String data="Hello SecondActivity";
intent.putExtra("extra_data",data);
startActivity(intent);
Intent intent=getIntent();
String data=intent.getStringExtra("extra_data");
Log.d("SecondActivity",data);
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivityForResult(intent,1);//第二个参数是请求码
子活动:
Intent intent = new Intent();
String data = "Hello FirstActivity";
intent.putExtra("data_return", data);
setResult(RESULT_OK, intent);//专用于向上一个活动返回数据,第一个参数是用于向上一个活动返回处理结果,一般是RESULT_OK,RESULT_CANCELED
finish();//销毁活动,回调onActivityResult,可以在此方法得到返回数据。
//按返回键销毁活动的回调函数
@Override
public void onBackPressed(){
Intent intent=new Intent();
intent.putExtra("data_return","Hello FirstActivity");
setResult(RESULT_OK, intent);
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");
Log.d("FirstActivity", returnedData);
}
break;
default:
break;
}
}
—-图来自android编程权威指南
3、我们还可以通过intent来传递对象
(a)、Serializable方式,将整个对象序列化。
只需要让该对象implement Serializable接口,写一系列set,get方法来为对象的数据做赋值和读取。
比如,FirstActivity:
Person person=new Person();
person.setName("TellH");
Person.setAge(20);
Intent intent=new Intent(FirstActivity.this,SecondActivity.class);
intent.putExtra("person_data",person):///假如Person类已经实现了Serializable接口
startActivity(intent);
SecondActivity:
Person person=(Person)getIntent().getSerializableExtra("person_data");
(b)、Parcelable方式:
public class Person implements Parcelable {
private String name;
private int age;
//需要重写一下两个方法
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {//将数据一一打包,写入Parcel
dest.writeString(name);
dest.writeInt(age);
}
//创建一个Parcelable.Creator<Person>接口的实现,重写两个方法
private static final Parcelable.Creator<Person> CREATOR=new Parcelable.Creator<Person>(){
@Override
public Person createFromParcel(Parcel source) {//从Parcel读取数据
Person person= new Person();
//这里的读出数据的顺序一定要和写入数据的顺序要一致
person.name=source.readString();
person.age=source.readInt();
return person;
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
}
这里深入了解一下intent的通信:
intent对象是component用来与操作系统通信的一种媒介工具。当调用startActivity()方法是,该方法把intent发送给操作系统的ActivityManager,ActivityManager负责创建Activity实例并调用其onCreate()方法,这种模式会使在不同应用间的Activity的交互变得容易得多。
1、返回栈(back stack==Task)
Task是一个具有栈结构的对象,一个Task就是一组activity的集合。这些activity按照它们打开的顺序被放置于一个先进后出的栈中(back stack)。用户点击图标打开一个app时,该app的task会被移到前台显示。如果当前没有该app的task,系统将会新建一个task并在其中运行Main activity。如果HOME键被按下,从当前app回到桌面,该app的Task会被移到后台,后台的task所属的所有activity都是stop状态,且back stack依然存在——这个task其实只是失去了和用户交互的焦点。
taskAffinity属性:每个Activity都有taskAffinity属性,这个属性指出了它希望进入的Task。如果一个Activity没有显式的指明该Activity的taskAffinity,那么它的这个属性就等于Application指明的taskAffinity,如果Application也没有指明,那么该taskAffinity的值就等于包名。而Task也有自己的affinity属性,它的值等于它的根Activity的taskAffinity的值。
Task与Activity,application的关系:
2、活动生存期
(a)、当任务被创建和销毁分别会回调onCreate()和onDestroy()
(b)、当任务进入前台或者解锁屏(由不可见到可见)和退出前台进入后台或者被锁屏(由可见到不可见)时分别会回调onStart()和onStop()
(c)、当任务(位于返回栈的栈顶)要准备与用户进行交互的时候回调onResume();
但当任务要准备被另一个活动或对话框覆盖,需要释放掉系统资源,保存关键数据,回调onPause(),此时任务仍然可见,但不能与用户进行交互。
(d)、但任务从stop状态变为start状态前,先回调onRestart()。
(e)、其他的Activity状态方法
onWindowFocusChanged方法:在Activity窗口获得或失去焦点时被调用,例如创建时首次呈现在用户面前;当前Activity被其他Activity覆盖;当前Activity转到其他Activity或按Home键回到主屏,自身退居后台;用户退出当前Activity。
onSaveInstanceState:(1)在Activity被覆盖或退居后台之后,系统资源不足将其杀死,此方法会被调用,此方法会被调用,此方法携带一个Bundle类型的参数,利用bundle.putString(或者putInt,put~)向bundle写入数据,在onCreate(Bundle savedInstanceState),或者onRestoreInstanceState(Bundle savedInstanceState),中获取数据,恢复之前活动被回收的状态;(2)在用户改变屏幕方向时,此方法会被调用;(3)在当前Activity跳转到其他Activity或者按Home键回到主屏,自身退居后台时,此方法会被调用。onSaveInstanceState的调用顺序是在onPause之前。
onRestoreInstanceState:(1)在Activity被覆盖或退居后台之后,系统资源不足时被回收,然后用户又回到了此Activity;(2)在用户改变屏幕方向时,重建的过程中,此方法会被调用。我们可以重写此方法,以便可以恢复一些临时数据。onRestoreInstanceState的调用顺序是在onStart之后。
在AndroidManifest中注册活动的时候配置,< activity android:launchMode=”?”>
(a)、standard,默认模式,每次启动该活动都会创建并往返回栈栈顶添加该活动的实例
(b)、singleTop,启动该活动前检查返回栈栈顶是否有该活动的实例,若有直接使用栈顶的实例,否则常见病往返回栈栈顶添加该活动的实例
(c)、singleTask,每次启动该活动前都会先检查是否存在与它的taskAffinity相同的Task。若存在该Task,检查Task是否有该活动的实例,若有直接使用栈顶的实例,并把这活动之上的所有活动统统出栈,否则创建并往返回栈栈顶添加该活动的实例,将该Task调到前台;若无则新建Task和该Activity实例,入栈。
(d)、singleInstance, 当要启动该活动时,如果该Activity没有被实例化,那么就重新创建一个Task并入栈,并保证不再有其他Activity实例进入(即这个task中永远只有一个activity),以便于其他应用程序共享该实例。如果已经被实例化,那么就调用该Activity的onNewIntent;任何从该Activity加载的其它Actiivty(假设为Activity2)都会被放入其它的Task中,如果存在与Activity2相同affinity的Task,则在该Task内创建Activity2。如果不存在,则重新生成新的Task并入栈。
singleInstance与singleTask的区别在于一个Task内只有一个Instance,活动的启动过程都是相似的。
在SecondActivity中添加一个actionStart()方法
public static void actionStart(Context context,String param1,String param2){
Intent intent=new Intent(context,SecondActivity.class);
intent.putExtra("param1",param1);
intent.putExtra("param2",param2);
context.startActivity(intent);
}
用一个List< Activity>管理Activity。
public class ActivityCollector{
public static List<Activity> activities=new ArrayList<>();
public static void addActivity(Activity activity){//在每次onCreate()调用
activities.add(activity);
}
public static void removeActivity(Activity activity){//在每次onDestroy()调用
activities.remove(activity);
}
public static void finishAll(){
for(Activity activity:activities){
if(!activity.isFinishing()){
activity.finish();
activities.remove(activity);
}
}
}
查阅和参考的资料:
基础总结篇之一:Activity生命周期:http://blog.csdn.net/liuhe688/article/details/6733407
基础总结篇之二:Activity的四种launchMode:http://blog.csdn.net/liuhe688/article/details/6754323
Android开发中任务和返回栈:http://www.android100.org/html/201402/22/5690.html
Android中的“Application”,“Task”,“Activities”的关系:http://blog.csdn.net/mengweiqi33/article/details/7670541
Activity的taskAffinity属性:http://blog.csdn.net/wangshione/article/details/8491249