zoukankan      html  css  js  c++  java
  • Android 四大组件之 Activity(二)

    1、综述

          Activity是Android四大组件(Application Components)之一,简单来说Activity就是平常所见到的用户界面,一般情况下,一个Activity所占的窗口是满屏的,但也可以是一个小的位于其它Activity之上的浮动窗口。一个Android工程至少有一个Activity,Activity上面可布有多个view实例,如文本框、进度条、复选框、按钮等等。多个Activity之间通过Intent来实现跳转。

    [1]新建一个activity

    (1)要继承(extends)Activity类,复写onCreate(bundle)方法,然后通过" setContentView() "绑定此activity的布局文件XML。

    public class secondactivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            // TODO Auto-generated method stub
            super.onCreate(savedInstanceState);
            setContentView(R.layout.secondactivity);//绑定布局文件
        }
    }
    

    (2)还必须在AndroidManifest.xml里面注册这个新增加的activity。

    <activity
           android:label="second"
           android:name=".secondactivity"   //activity所在.java类 
     >
    </activity>
    

    2、Intent的类来实现屏幕之间的跳转:

    [1]显示意图跳转:要求必须知道被激活组件的包和class。

    应用场景:在应用程序内部进行跳转。 缺点:耦合性较高。

    常规使用方式:

    (1)在layout中的" activity_main.xml " 中加入一个id为btn的按钮,另外再创建一个任意的layout(将要跳转到得layout),我取名为second。

    (2)在java包中新增" SecondActivity.jar "作为目标Activity,如下:

    package com.myandroid;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;
    public class SecondActivity extends Activity  {
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.second);
    	}
    }
    

    (3)在AndroidManifest中加入一个新的activity标签,至少要声明一个android:name属性,如下:

    <activity android:name=".SecondActivity">  
    </activity> 
    

    (4)在起始Activity中添加跳转,需引入import android.content.Intent;命名空间,如下:

    package com.myandroid;
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.Button;
    import android.content.Intent;
    
    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
    	setContentView(R.layout.activity_main);
    	Button button = (Button) this.findViewById(R.id.btn);
    	button.setOnClickListener(new View.OnClickListener(){
    	    @Override
    	    public void onClick(View v) {
    		Intent intent = new Intent();    //实例化Intent类
              //第一个参数是Context,第二个参数是跳转Activity的类 
    		intent.setClass(MainActivity.this, SecondActivity.class);    //跳转
    		startActivity(intent);    //启动
    		finish();//停止当前的Activity,如果不写,则按返回键会跳转回原来的Activity		
    	    }
            });
        }
    }
    

    另外两种显示方式:

    /*** 方法一 ***/ 
    Intent intent1 = new Intent(); 
    //参数一是当前的包名,参数二跳转activity的类名,一定要加上包名 
    intent1.setClassName("com.myandroid", "com.myandroid.SecondActivity"); 
    startActivity(intent1);
    
    /*** 方法二 ***/
    Intent intent3 = new Intent();
    // 参数一是当前的包名,参数二跳转activity的类名,一定要加上包名 
    ComponentName component = new ComponentName("com.myandroid", "com.myandroid.SecondActivity"); 
    intent3.setComponent(component); 
    startActivity(intent3);
    

    [2]隐式意图:只需要知道跳转activity的动作和数据,就可以激活对应的组件。

    应用场景:在不知道某一应用程序的类名,包名,并且引用不到时。可以跳转到其他应用。带参数访问浏览器的实现。 优点:耦合性较低。

    注意:data与type不可以分开写,使用setDataAndType()方法 常规使用方式:

    (1)在AndroidManifest中加入一个新的activity标签,要用隐式的意图激活Activity,就要设置动作,类别,数据三个参数,Action及Category的名称是可以自己定义的,只要与openOtherActivity方法中对Intent的设置相一致就可以被过滤器找到并最终激活。如下:

    <activity android:name=".SecondActivity">  
           <intent-filter>
                 <action android:name="com.myandroid.SecondActivity" />
                 <category android:name="com.myandroid.Default" />
    </intent-filter> </activity>

    (2)对Intent的设置如下。

    /*** 隐式意图***/ 
    Intent intent = new Intent(); 
    
    //只要动作名称与过滤器中的动作名称一致,就可以匹配,如果匹配成功就可以查看类别及数据
    //如果没有类别及数据,那么只会匹配动作
    intent.setAction("com.android.SecondActivity"); 
    intent.addCategory("com.android.Default");
    
    //startActivity(intent)为Intent对象注入了一个android.intent.category.DEFAULT类别,必须添加该类别,不然报错找不到activity;
    //intent.addCategory("android.intent.category.DEFAULT"); 
    
    startActivity(intent); 
    

    运行发现报错:

    原因:startActivity(intent)为Intent对象注入了一个android.intent.category.DEFAULT类别,必须添加该类别,不然报错找不到activity;

    解决:在AndroidManifest中对应的activity中的intent-filter下,添加对应的<categoryandroid:name="android.intent.category.DEFAULT"/>类别。

    此时运行程序,可以跳转成功。

    结论:只要Intent设置中的action及category在intent-filter中出现,就可以成功跳转,前提是在没有设置数据参数的情况下。

    (3)添加参数的情况:

    1)加入的数据是Uri类型的,上面代码的意思是匹配以itcast开头的,主机名为www.itcast.com的数据,后面的路径没有要求:

    <activity android:name=".SecondActivity">  
           <intent-filter>
                 <action android:name="com.myandroid.SecondActivity" />
                 <category android:name="com.myandroid.Default" />
            <data
                        android:host="cn.host.android"
                        android:scheme="host" />
           </intent-filter>
    </activity>

    2)在startActivity(intent)前添加设置data属性,如下:

    // 如果在声明activity的时候指定了data属性,就一定要设置他的data属性值,和配置的属性值相等
    intent.setData(Uri.parse("host://cn.host.android/my")); 
    

    此时运行程序,可以跳转成功。

    (4)对数据类型进行设置:

    1)在intent-filter中添加设置:<data android:mimeType="image/*" />这句代码的意思是对image及所有的图片数据进行匹配。

    2)在Intent对象中进行设置:intent.setType("image/jpeg");

    运行发现报错:

    原因:添加了setType()方法后,会自动清除intent.setData()方法中的数据设置,所以匹配数据不一致导致了失败,即使将intent.setType("image/jpeg");放在setData()方法之前也是不成功的。

    解决方法:把setData()及setType()方法删除,然后,采用Intent对象的setDataAndType(),同时设置数据与类型就可以了,如下。

    intent.setDataAndType(Uri.parse("host://cn.host.android/my"),"image/jpeg");

    此时运行程序,可以跳转成功。

    3、Intent数据传递

    应用场景:传递数据,RP计算器。

    Bundle:数据捆,打包传输

    [1]方式一:

    (1)发送页面

    Intent intent = new Intent();
    intent.setClass(MainActivity.this, SecondActivity.class);
    Bundle bundle = new Bundle();     //打包发送
    bundle.putString("name","123");    //绑定参数
    intent.putExtra("maps",bundle);
    startActivity(intent);
    

    (2)接收页面

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        TextView tv = new TextView(this);
        Intent intent = this.getIntent();
        Bundle bundle = intent.getBundleExtra("maps");     //获取打包数据bundle
        String name = bundle.getString("name");     //取出需要的数据
        tv.setText(name);
        setContentView(tv);
    }

    或者

    @Override
     protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.second);
      TextView txt = (TextView)this.findViewById(R.id.txt);
      Intent intent = this.getIntent();
      Bundle bundle = intent.getBundleExtra("maps");     //获取打包数据bundle
      String name = bundle.getString("name");     //取出需要的数据
      txt.setText(name);
     }

    [2]方式二:创建对象类(javabean)Person,实现Serializable接口

    private static final long serialVersionUID = 1L;

    (1)发送页面

    Intent inent = new Intent();

    intent.setClass(this,secondActivity.class);

    Person person = new Person(name);     //序列化对象传递

    intent.putExtra("person',person);

    startActivity(intent);

    (2)接收页面

    TextView tv = new TextView(this);

    Intent intent = this.getIntent();

    Person p = (Person)intent.getSerializableExtra("person');

    String name = p.getName();

    4、Intent返回数据

    [1]跳转前的Activity:

      如果想在Activity中得到新打开Activity关闭后返回的数据,需要使用Activity提供的 startActivityForResult(Intent intent,int requestCode) (startActivity()是context提供的抽象方法,而startActivityForResult方法是Activity自己特有的方法)方法打开新的Activity,新的Activity关闭后会向前面的Activity  传回数据,为了得到传回的数据,必须在" 跳转前页面 "的Activity中重写onActivityResult(int requestCode, intresultCode, Intent data)方法。

    实例:

    (1)改为用startActivityForResult(Intent intent,int requestCode)跳转;

    Button button = (Button) this.findViewById(R.id.btn);
    button.setOnClickListener(new View.OnClickListener(){
    
    	@Override
    	public void onClick(View v) {
    	    Intent intent = new Intent();
    	    intent.setClass(MainActivity.this, SecondActivity.class);
    	    //第二个参数为请求码,可以根据业务需求自己编号
    	    startActivityForResult (intent,  1);		    	
    	}
    		        	
    });
    

    (2)重写onActivityResult(int requestCode, intresultCode, Intent data)方法;

    //第一个参数为请求码,即调用startActivityForResult()传递过去的值
    //第二个参数为结果码,结果码用于标识返回数据来自哪个新Activity
    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    
        if(requestCode == 1 && resultCode == Activity.RESULT_OK)
       {
            String result = data.getExtras().getString("result");//得到新Activity关闭后返回的数据
          TextView tv = (TextView)this.findViewById(R.id.txtBack);
          tv.setText(result);
       }
    }

    [2]跳转后的Activity返回数据:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second);
        Button button = (Button) this.findViewById(R.id.back);
        button.setOnClickListener(new View.OnClickListener(){
    
            @Override
            public void onClick(View v) {
    	    Intent intent = new Intent();//数据是使用Intent返回
    	    intent.putExtra("result", "成功返回结果");//把返回数据存入Intent
    	    SecondActivity.this.setResult(RESULT_OK,intent);//设置返回数据
    	    SecondActivity.this.finish();//关闭Activity    	
            }
    		        	
        });
    }
    

    注意:

    [1]setResult()方法是Activity的特有方法,第一个参数值RESULT_OK是系统Activity类定义的一个常量,值为-1。

    [2]在Activity A中打开一个Activity B,如果要在Activity B关闭的时候给Activity A传一些数据,那么在startActivityForResult (intent,  1)后不可以再使用MainActivity.this.finish();

    5、横竖屏切换Activity的生命周期

    默认情况下会重新加载activity,容易重新加载数据,造成数据丢失。如游戏。

    具体流程:onPause -> onStop ->onDestory -> onCreate ->onStart ->onResume
    避免横竖屏切换重新创建activity 在清单文件的activity节点中加入:android:configChanges="orientation|keyboardHidden "

    6、任务栈

    为了提高用户体验 一个应用程序包含多个activity 栈的顶部的activity会在界面中显示,获取焦点。

    任务栈的特点:先进后出,后进先出。

    7、AndroidManifest中的activity组件

    AndroidManifest文件中含有如下过滤器的activity组件为默认启动组件,应用程序启动时,系统自动调用它。

  • 相关阅读:
    beta冲刺总结-咸鱼
    咸鱼翻身beta冲刺博客集
    事后诸葛亮
    个人作业——软件产品案例分析
    Alpha冲刺博客集
    结对作业第二次
    项目需求分析(团队)
    第二次作业——个人项目实战
    软件工程实践第一次作业--准备
    beta冲刺总结
  • 原文地址:https://www.cnblogs.com/xinaixia/p/4096868.html
Copyright © 2011-2022 走看看