Android學習筆記(三五):再談Intent(下)-一些實踐

來源:互聯網
上載者:User

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開發相關文章

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.