欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

全面解析Android应用开发中Activity类的用法

程序员文章站 2024-02-26 14:39:34
activity类处于android.app包中,继承体系如下: 1.java.lang.object 2.android.content.context 3.and...

activity类处于android.app包中,继承体系如下:
1.java.lang.object
2.android.content.context
3.android.app.applicationcontext
4.android.app.activity
activity是单独的,用于处理用户操作。几乎所有的activity都要和用户打交道,所以activity类创建了一个窗口,开发人员可以通过setcontentview(view)接口把ui放到activity创建的窗口上,当activity指向全屏窗口时,也可以用其他方式实现:作为漂浮窗口(通过windowisfloating的主题集合),或者嵌入到其他的activity(使用activitygroup)。大部分的activity子类都需要实现以下两个接口:
oncreate(bundle)接口是初始化activity的地方. 在这儿通常可以调用setcontentview(int)设置在资源文件中定义的ui, 使用findviewbyid(int) 可以获得ui中定义的窗口.
onpause()接口是使用者准备离开activity的地方,在这儿,任何的修改都应该被提交(通常用于contentprovider保存数据).
为了能够使用context.startactivity(),所有的activity类都必须在androidmanifest.xml文件中定义有相关的“activity”项。
activity类是android 应用生命周期的重要部分。下面我们具体来总结一下activity的各个要点:
一、activity的生命周期

全面解析Android应用开发中Activity类的用法

二、activity之间传递数据
1. 通过intent传递数据
通过intent.putextra方法可以将简单数据类型或可序列化对象保存在intent对象中,然后在另一个activity中使用getint、getstring等方法获得这些数据。示例代码如下:

intent intent =new intent(currentactivity.this,otheractivity.class);
 // 创建一个带“收件人地址”的 email 
 bundle bundle =new bundle();// 创建 email 内容
 bundle.putboolean("boolean_key", true);// 编写内容
 bundle.putstring("string_key", "string_value"); 
 intent.putextra("key", bundle);// 封装 email 
 startactivity(intent);// 启动新的 activity

下面是获取数据:

 intent intent =getintent();// 收取 email 
 bundle bundle =intent.getbundleextra("key");// 打开 email 
 bundle.getboolean("boolean_key");// 读取内容
 bundle.getstring("string_key");

不过使用bundle传递数据稍显麻烦,如果你只需要传递一种类型的值可以这样:

intent intent =new intent(ex06.this,otheractivity.class); 
 intent.putextra("boolean_key", true); 
 intent.putextra("string_key", "string_value"); 
 startactivity(intent);

获取数据:

intent intent=getintent(); 
 intent.getbooleanextra("boolean_key",false); 
 intent.getstringextra("string_key");

2. 通过静态变量传递数据
适用于不可序列化的且简单的对象,不过不推荐使用静态代码块

public class mainactivity extends activity { 
  private button btn; 
  @override 
  public void oncreate(bundle savedinstancestate) { 
    super.oncreate(savedinstancestate); 
    setcontentview(r.layout.main); 
    btn = (button)findviewbyid(r.id.btopenotheractivity); 
    btn.setonclicklistener(new onclicklistener() { 
      @override 
      public void onclick(view v) { 
        //定义一个意图 
        intent intent = new intent(mainactivity.this,otheractivity.class); 
        //改变otheractivity的三个静态变量的值 
        otheractivity.name = "wulianghuan"; 
        otheractivity.age = "22"; 
        otheractivity.address = "上海闵行"; 
        startactivity(intent); 
      } 
    }); 
  } 
}
public class otheractivity extends activity { 
  public static string name; 
  public static string age; 
  public static string address; 
  private textview text_name; 
  private textview text_age; 
  private textview text_address; 

  @override 
  public void oncreate(bundle savedinstancestate) { 
    super.oncreate(savedinstancestate); 
    setcontentview(r.layout.other); 
    text_name = (textview) findviewbyid(r.id.name); 
    text_age = (textview) findviewbyid(r.id.age); 
    text_address = (textview) findviewbyid(r.id.address);   
    //设置文本框的数据 
    text_name.settext("姓名:"+name); 
    text_age.settext("年龄:"+age); 
    text_address.settext("地址:"+address); 
  } 
}

3.通过全局对象传递数据
如果想使某些数据长时间驻留内存,以便程序随时调用,建议采用全局对象。application全局类不需要定义静态变量只要定义普通成员变量即可,但全局类中必须有一个无参构造方法,编写完application类后,还需要在<application>标签中制定全局类名,否则系统不会自动创建全局对象。

public class mainapplication extends application {
  private string username;

  public string getusername() {
    return username;
  }

  public void setusername(string username) {
    this.username = username;
  }
}
public class mainactivity extends activity {

  private mainapplication application;

  public void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);
    application = (mainapplication) getapplication();
    application.setusername("sunzn");
  }

  public void open(view view) {
    intent intent = new intent(this, otheractivity.class);
    startactivity(intent);
  }
}
public class otheractivity extends activity {
  private textview tv_data;
  private mainapplication application;
  private string username;

  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_other);
    application = (mainapplication) getapplication();
    username = application.getusername();
    tv_data = (textview) findviewbyid(r.id.tv_data);
    tv_data.settext("从上一个 activity 中获取到的数据为:" + username);
  }
}

三、从activity返回数据
要从activity返回数据,需要使用startactivityforresult方法来显示activity。
从activity1跳转到activity2:

intent intent = new intent();
 intent = intent.setclass(activityintent.this, anotheractivity.class);
 bundle bundle = new bundle();
 bundle.putstring("string", et_string.gettext().tostring());
 intent.putextras(bundle);
 startactivityforresult(intent,0); //只有这里不同

从activity2返回数据到aactivity1:

intent intent = new intent();
intent = intent.setclass(anotheractivity.this, activityintent.class);
bundle bundle = new bundle();
bundle.putint("result", "activity2的处理结果");
intent.putextras(bundle); 
anotheractivity.this.setresult(result_ok, intent); //result_ok是返回状态码
anotheractivity.this.finish();

在activity1中重写onactivityresault方法,接受数据:

protected void onactivityresult(int requestcode, int resultcode, intent data) {
          super.onactivityresult(requestcode, resultcode, data);
          switch(resultcode) { //根据状态码,处理返回结果
          case result_ok: 
             bundle bundle =data.getextras(); //获取intent里面的bundle对象
               string result = bundle.getint("result"); 
          break; 
          default:
          break;
          } 

       }

四、activity的四种创建模式
我们在开发项目的过程中,会涉及到该应用中多个activity组件之间的跳转,或者夹带其它应用的可复用的activity。例如我们可能希望跳转到原来某个activity实例,而不是产生大量重复的 activity。这样就需要我们为 activity 配置特定的加载模式,而不是使用默认的加载模式。设置启动模式的位置在 manifest.xml 文件中 activity的android:launchmode 属性

1.standard 模式
这是默认模式,无需设置,每次激活activity时都会创建activity实例,并放入任务栈中。相当于入栈,按back键返回到前一个activity相当于退栈。

2.singletop 模式
如果在任务的栈顶正好存在该activity的实例,就重用该实例( 会调用实例的 onnewintent()),否则就会创建新的实例并放入栈顶,即使栈中已经存在该activity的实例,只要不在栈顶,都会创建新的实例。可用来解决栈顶多个重复相同的activity的问题

3.singletask 模式
如果在栈中已经有该activity的实例,就重用该实例(会调用实例的 onnewintent() )。重用时,会让该实例回到栈顶,因此在它上面的实例将会被移出栈。如果栈中不存在该实例,将会创建新的实例放入栈中。singletask 模式可以用来退出整个应用。将主activity设为singtask模式,然后在要退出的activity中转到主activity,然后重写主activity的onnewintent函数,并在函数中加上一句finish。

4.singleinstance 模式
在一个新栈中创建该activity的实例,并让多个应用共享该栈中的该activity实例。一旦该模式的activity实例已经存在于某个栈中,任何应用再激活该activity时都会重用该栈中的实例( 会调用实例的 onnewintent() )。其效果相当于多个应用共享一个应用,不管谁激活该 activity 都会进入同一个应用中。

五、activity现场保存状态
一般来说,调用onpause()和onstop()方法后的activity实例仍然存在于内存中,activity的所有信息和状态数据不会消失, 当activity重新回到前台之后, 所有的改变都会得到保留。但是当系统内存不足时, 调用onpause()和onstop()方法后的activity可能会被系统摧毁, 此时内存中就不会存有该activity的实例对象了. 如果之后这个activity重新回到前台, 之前所作的改变就会消失.可以在activity被杀掉之前调用保存每个实例的状态,开发者可以覆写onsaveinstancestate()方法. onsaveinstancestate()方法接受一个bundle类型的参数, 开发者可以将状态数据存储到这个bundle对象中,以保证该状态在oncreate(bundle)或者onrestoreinstancestate(bundle)(传入的bundle参数是由onsaveinstancestate封装好的)中恢复。这个方法在一个activity被杀死前调用,当该activity在将来某个时刻回来时可以恢复其先前状态。如果调用onsaveinstancestate()方法,调用将发生在onpause()或onstop()方法之前,而且它也不是生命周期的方法。
若向数据库中插入记录等,保存持久化数据的操作应该放在onpause()中. onsaveinstancestate()方法只适合保存瞬态数据, 比如ui控件的状态, 成员变量的值等.

public class mainactivity extends activity { 
  private string temp;  
  @override 
  public void oncreate(bundle savedinstancestate) { 
    super.oncreate(savedinstancestate); 
    // 从savedinstancestate中恢复数据, 如果没有数据需要恢复savedinstancestate为null 
    if (savedinstancestate != null) { 
      temp = savedinstancestate.getstring("temp"); 
      system.out.println("oncreate: temp = " + temp); 
    } 
  } 

  public void onrestoreinstancestate(bundle saveinstancestate) { 
    super.onrestoreinstancestate( saveinstancestate); 
    string temp = saveinstancestate.getstring("temp"); 
    system.out.println("onresume: temp = " + temp); 

  } 

  // 将数据保存到outstate对象中, 该对象会在重建activity时传递给oncreate方法和onrestoreinstancestate方法
  @override 
  protected void onsaveinstancestate(bundle outstate) { 
    super.onsaveinstancestate(outstate); 
    outstate.putstring("temp", temp); 
  }

六、一些关于activity的技巧
1.设置activity的方向

android:screenorientation="portrait">// 竖屏 , 值为 landscape 时为横屏

2.设置activity全屏
在oncreate方法中添加如下代码:

// 设置全屏模式
getwindow().setflags(windowmanager.layoutparams.flag_fullscreen, 
 windowmanager.layoutparams.flag_fullscreen); 
// 去除标题栏
requestwindowfeature(window.feature_no_title);

改变窗口大小、位置、透明度
在oncreate方法中添加如下代码:

window w=getwindow();
w.setbackgrounddrawableresource(resourceid);//设置窗口背景
windowmanager.layoutparams layoutparams = w.getattributes();
layoutparams.height = 200; 
layoutparams.width= 200;
layoutparams.gravity = gravity.top;
layoutparams.x=50;//距离gravity属性的距离
layoutparams.y=50;
layoutparams.alpha = 0.5;//0:完全透明,1:不透明
w.setattributes(layoutparams);

3.关闭所有窗口

intent intent = new intent(); 
intent.setclass(android123.this, cwj.class); 
intent.setflags(intent.flag_activity_clear_top); //注意本行的flag设置 
startactivity(intent)

另一种方法:在调用退出方法中写上myapplication.getinstance().exit();

public class myapplication extends application {

   private list<activity> activitylist = new linkedlist<activity>();
   private static myapplication instance;

   private myapplication() {
   }

   // 单例模式中获取唯一的myapplication实例
   public static myapplication getinstance() {
       if (null == instance) {
           instance = new myapplication();
       }
       return instance;

   }

   // 添加activity到容器中
   public void addactivity(activity activity) {
       activitylist.add(activity);
   }

   // 遍历所有activity并finish
   /*
   * 在每一个activity中的oncreate方法里添加该activity到myapplication对象实例容器中
   * 
   * myapplication.getinstance().addactivity(this);
   * 
   * 在需要结束所有activity的时候调用exit方法
   * 
   * myapplication.getinstance().exit();
   */
   public void exit() {

       for (activity activity : activitylist) {
           activity.finish();
       }

       system.exit(0);

   }