Android学习笔记(三五):再谈Intent(下)-一些实践

Android的UI框架要求用户将他们的app分为activity,通过itent来进行调度,其中有一个main activity由Android的launcher在桌面中调用。例如一个日历的应用,需要查看日历的activity,查看单个事件的activity,编辑事件的activity等等。在查看日历的activity中,如果用户选择的某个事件,需要通过查看事件的activity来处理。这就是最近本的app UI框架,本次,我们将学习如何通过intent来完成。

Activity之间的关系

某种业务逻辑下,activity1需要知道被调起的activity2是否结束,activity2就是activity1的subactivity。

另一些业务逻辑下,activity1并不需要了解被它调起的activity2的运行情况,例如在邮件中打开一个附件,邮件activity1并不需要了解查看附件activity2是否结束。这种情况下,两个activity不是主从关系,而是peer关系,activity2是一个常规的activity。

步骤1:Make the Intent

intent会封装一个请求给Android,使得其他activity或者intent receiver知道如何处理。如果intent要launch的activity是我们自己编写的,可以很容易通过一个精确指定的intent来实现,例如:

new Intent(this, HelpActivity.class);

其中HelpActivity.class就是我们需要launch的component。这个activity只需要在AndroidManifest.xml文件中定义,但是不需要任何的inter filter,因为是通过直接请求的方式。如果我们需要打上一些data,即Uri,请求一个通用的activity,如下:

Uri uri=Uri.parse("geo:"+lat.toString()+","+lon.toString());
Intent i=new Intent(Intent.ACTION_VIEW, uri);

步骤2:Make the Call

根据activity之间的关系,通过intent的方法startActivity()或者startActivityForResult()来launch另一个activity。后者是需要知道activity2是否运行结束,以及运行的结果。

startActivityForResult()会向intent传递一个数字,这个数字对于calling activity来讲是唯一的。用于区分哪个activity。被调起的activity运行完,会在calling activity中触发onActivityResult(),我们可以通过这个唯一的数字来区分到底是哪个被调起的activity运行结束。我们还会得到下面的信息:

  1. result code,通过被调起的activity用setResult()来设置,一般是RESULT_OK和RESULT_CANCELLED,当然我们也可以定义我们自己的返回值,(从RESULT_FIRST_USER开始定义)
  2. 可选的String,用于传递某些返回信息,例如是一个URL来表述某个资源,有例如在ACTION_PICK中返回用户选取内容的数据。
  3. 可选的Bundle,用于返回所需的信息

例子一:一个简单的调用

例子通过输入经纬度,然后通过intent去launch地图应用。布局文件如下,顺带复习一下TableLayout的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout ...... > 
  <TableLayout android:layout_width="fill_parent"   android:layout_height="wrap_content"
    android:stretchColumns="1,2"> 
      <TableRow> 
              <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
                android:paddingLeft="2dip" android:paddingRight="4dip" 
                android:text="Location:" /> 
              <EditText android:id="@+id/c18_lat" 
                android:layout_width="fill_parent"  android:layout_height="wrap_content"
                android:cursorVisible="true" 
                android:editable="true" 
                android:singleLine="true"  
                android:layout_weight="1"/> 
              <EditText android:id="@+id/c18_lon" 
                android:layout_width="fill_parent" android:layout_height="wrap_content"
                android:cursorVisible="true" 
                android:editable="true" 
                android:singleLine="true" 
                android:layout_weight="1" /> 
      </TableRow> 
  </TableLayout> 
        <Button android:id="@+id/c18_map"  android:layout_width="fill_parent" android:layout_height="wrap_content"
          android:text="Show Me!" /> 
</LinearLayout>

源代码如下:

public class Chapter18Test1 extends Activity{
    private EditText latitude = null; 
    private EditText longtitude =null;

protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.chapter_18_test1);

latitude = (EditText)findViewById(R.id.c18_lat);
        longtitude = (EditText)findViewById(R.id.c18_lon); 
        Button button = (Button)findViewById(R.id.c18_map); 
        button.setOnClickListener(new View.OnClickListener() { 
            public void onClick(View v) { 
                String _lat = latitude.getText().toString();
                String _lon = longtitude.getText().toString(); 
                //由于AVD缺乏地图应用,所以在模拟器中,会无法触发geo:作为URI的应用,会出现报错,如果仍然使用模拟器,可通过Web浏览的方式。例子采用模拟器。
                //Uri uri=Uri.parse("geo:" + _lat + _lon);
                Uri uri=Uri.parse("http://maps.google.com/?q=" +_lat + "," + _lon);
                startActivity(new Intent(Intent.ACTION_VIEW,uri)); 
            } 
        }); 
    } 
}

例子二:Tab Browser

我们可以回顾一下Android学习笔记(二二): 多页显示-Tag的使用中最后一个例子,在Tab中显示Acitvity。如果我们需要将Activity作为content在tab中显示,我们提供一个Intent来launch所需的activity。在这个例子中,我们将在Tab的内容中通过intent调起网页浏览。

如果我们直接使用

Intent intent=new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(http://commonsware.com));

然后在tab中setContent(intent);我们会发现不能争取工作,因为在Android中,基于安全考虑,不能在tab中加载其他app的activity。因此我们需要自己来写。我们先写两个嵌入webkit browser的浏览器。

public class Chapter18Test2_1 extends Activity{
    private WebView browser = null;   
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState); 
        browser = new WebView(this); 
        setContentView(browser); 
        browser.loadUrl("http://commonsware.com"); 
    } 
}
public class Chapter18Test2_2 extends Activity{
    private WebView browser = null;   
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState); 
        browser = new WebView(this); 
        setContentView(browser); 
        browser.loadUrl("http://www.android.com"); 
    } 
}

calling activity的源代码如下,很简单

public class Chapter18Test2 extends TabActivity{ //使用TabActivity,已经有Tab的布局,因此我们不再需要布局xml文件。
    private TabHost host = null;

protected void onCreate(Bundle savedInstanceState) { 
       super.onCreate(savedInstanceState); 
        host=getTabHost(); 
        host.addTab(host.newTabSpec("one").setIndicator("CW").
                setContent(new Intent(this,Chapter18Test2_1.class)));
        host.addTab(host.newTabSpec("Two").setIndicator("Android"). 
                setContent(new Intent(this,Chapter18Test2_2.class)));
    } 
}

我们回头在来看看这个例子的代码,同样的打开某个webkit browser的URL使用了两个activity,两个class,这是相当浪费的。我们可以将URL作为Intent的extra的信息传递。我们将上面的例子修改一下,通过Bundle来传递extra信息,并在calling activity中,可以很方便地增加tab。

被调用的activity:

public class Chapter18Test2_0 extends Activity{
    private WebView browser = null; 
    protected void onCreate(Bundle savedInstanceState) { 
       super.onCreate(savedInstanceState); 
        browser = new WebView(this); 
        setContentView(browser); 
        Bundle bundle = getIntent().getExtras(); 
        browser.loadUrl(bundle.getString("http_uri"));
    } 
}

calling的activity:

public class Chapter18Test2 extends TabActivity{
    private TabHost host = null; 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        host=getTabHost(); 
        addTab("one","CW","http://commonsware.com"); 
        addTab("Two","Android","http://www.android.com");
        addTab("Three","Blog","http://blog.csdn.net/flowingflying/");
    } 
  //增加一个方法,用于添加tab 
    private void addTab(String tag, String indicator, String uri){ 
        Bundle bundle = new Bundle(); 
        bundle.putString("http_uri",uri); 
        Intent intent = new Intent(this,Chapter18Test2_0.class); 
        intent.putExtras(bundle); 
        host.addTab(host.newTabSpec(tag).setIndicator(indicator).setContent(intent));
    } 
}

相关链接: 我的Android开发相关文章

时间: 2024-08-24 16:26:27

Android学习笔记(三五):再谈Intent(下)-一些实践的相关文章

Android 学习笔记(10)—— Intent 基本运用

作者:夏至 欢迎转载,也请保留这段申明,谢谢 最近太忙了,都没什么时间来整理,前9个上传之后格式不对,都没好好整理,以后会抽空整理. Android的通信桥梁 -- Intent . 使用一个activity实在是太简单了,布局上也有限,那我们能不能像我们真机上的一样,一点就跳到另一个界面去了.这里我们就使用Intent,在活动中穿梭.至于为什么学着UI组件,突然跑到这个家伙来,那当然是为下一节做准备啦.除了活动,它还可以是服务或者广播.启动可以下列方法: startActivity(Inten

IBatis.Net学习笔记六--再谈查询

在IBatis.Net学习笔记五--常用的查询方式 中我提到了一些IBatis.Net中的查询,特别是配置文件的写法. 后来通过大家的讨论,特别是Anders Cui 的提醒,又发现了其他的多表查询的方式.在上一篇文章中我提到了三种方式,都是各有利弊:第一种方式当数据关联很多的情况下,实体类会很复杂:第二种方式比较灵活,但是不太符合OO的思想(不过,可以适当使用):第三种方式最主要的问题就是性能不太理想,配置比较麻烦. 下面是第四种多表查询的方式,相对第二种多了一点配置,但是其他方面都很好(当然

Android学习笔记(八) Intent

在一开始学习Android的过程中,对于Intent并没有太深入的理解,以为Intent只是作为一个传数据的中间对象,但是随着学习内容的增多,发现Intent的机制实际上贯穿于整个Android的过程: 1.Intent启动:Intent的传输数据只是作为其中一个重要的功能而存在,但是其更重要的作用在于启动/调用的机制,Android如何启动/调用一个应用.组件,首先需要的是一个定位的过程,需要启动哪个组件?指定的某个组件.或者是某个类型的组件,通过抽象成Intent进行统一的调用,只要对Int

Android学习笔记(十一) Intent

一.Intent对象的基本概念 -Intent是Android应用程序组件之一 -Intent对象在Android系统当中表示一种意图 -Intent当中最重要的内容是action与data 二.Intent对象的基本使用方法 Intent intent = new Intent(); intent.setClass(MainActivity.this,OtherActivity.class); //此处放入putExtra语句用于存放数据 startActivity(intent); 三.使用

Android学习笔记三:用Intent串联activity

一:Intent Intent可以理解为 意图. 我们可以通过创建intent实例来定义一个跳转意图,意图包括:要跳转到哪个页面.需要传递什么数据. 然后通过startActivity(intent)来启动跳转. 有两种方式定义Intent:显式Intent.隐式Intent. 二:显式Intent 1)我们可以在actvity的java文件中,通过代码显示定义Intent,参数为:从哪个页面,跳转到哪个页面. Intent intent = new Intent(FirstActivity.t

Python学习笔记(六)再谈Python模块

Python程序包含多个模块文件,一个主体.顶层文件实现主要控制流程.调用组件和工具,其他模块文件则提供组件和工具,python自带了许多实用的模块称为标准链接库.模块是python中最高级别的程序组织单元,将代码和数据封装起来以便重用.每一个文件都是一个模块,并且可以通过"导入"来使用其他模块的变量(顶层定义的所有变量).模块被导入时就生成了一个模块对象.从抽象的角度看,模块的作用有: 1)代码重用-模块文件的代码可以永久保存,可以被多个客户端使用.任意的重新运行和重载 2)划分系统

Android学习笔记(三四):再谈Intent(上)-一些知识

在Android学习笔记(七):多个Activity和Intent中,我们先在学会了如何使用intent在代码中唤起activity.此处作深一步地学习. 什么是Intent intent是对一个操作处理的抽象描述.context可以在使用startActivity(intent)来launch一个actvivity,就如我们在学习笔记(七)中的处理,也是最常用的方式,将activity在我们的应用中整合:可以在通过sentBroast(intent)来广播给任何有兴趣的BroadcastRec

Pro Android学习笔记(十二):了解Intent(下)

解析Intent,寻找匹配Activity 如果给出component名字(包名.类名)是explicit intent,否则是implicit intent.对于explicit intent,关键就是component 名字,在<intent-fliter>中声明的其他属性被忽略.对于implicit intent,则根据action,category和data来进行匹配.然而一个intent fliter中可以声明多个actions,多个categories,多个data属性,因此可以满

Android学习笔记(三七):再谈屏幕切换

切换需注意数据保存和恢复 在Android学习笔记(三六):横屏竖屏的切换中,我们配置了两个layout,一个用户普通的portrait,一个用户landsapce方式.如果只有一个layout,我们沿用上一个例子,删除了在layout-land/中的xml文件,则在屏幕切换时,会按照原来的排版,适配新的屏幕.程序我进行了简化,每按一次pick,就加一,用此来跟踪是否需要进行数据保存和恢复,如下: [java] view plaincopy public class Chapter19Test3