Giới thiệu
Ở viết trước đây Vòng đời của Activity trong Android (Activity LifeCycle) tôi đã giới thiệu cho các bạn khái niệm Activity cũng nhưng vòng đời của nó. Và chúng ta thấy rằng trong một ứng dụng có rất nhiều Activity. Vậy cách chuyển đổi và truyền dữ giữa các activity như thế nào hay nhận dữ liệu khi đóng activity như thế nào thì bài viết này tôi sẽ cùng các bạn làm rõ.
Ví dụ trong bài viết được thực hiện trên Android Studio 2.1 Ubuntu 14 64bit.
Chuyển đổi Activity trong kèm theo dữ liệu
Việc chuyển đổi Activity mà không gửi kèm dữ liệu cực kì đơn giản. Chúng ta chỉ cần tạo một đối tượng Intent sử dụng Constructor dưới đây
1 |
public Intent(Context packageContext, Class<?> cls) { |
Với đối số thứ nhất bạn truyền vào là Activity hiện tại.
Và đối số thứ hai là Activity mà bạn muốn chuyển hướng.
Ví dụ tôi muốn chuyển hướng từ MainActivity sang AboutAcitivity thì tôi sẽ tạo Intent như sau:
1 |
Intent intent = new Intent(MainActivity.this, AboutActivity.class); |
Or
1 |
Intent intent = new Intent(this, AboutActivity.class); |
Và cuối cùng để thực hiện chuyển Activity chúng ta sử dụng method của lớp Context.
1 |
public void startActivity(Intent intent) |
Ví dụ dưới đây tôi có 1 button trong MainActivity khi nhấn button này sẽ thực hiện chuyển sang AboutActivity như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
package com.nguyennghia.eitguide.activitydemo; import android.content.Intent; import android.graphics.Color; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.FrameLayout; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); FrameLayout frameLayout = new FrameLayout(this); frameLayout.setBackgroundColor(Color.parseColor("#ecf0f1")); Button btnNavi = new Button(this); btnNavi.setText("Navigate To About Activity"); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.gravity = Gravity.CENTER; frameLayout.addView(btnNavi, params); setContentView(frameLayout); //navigate to AboutActivity btnNavi.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, AboutActivity.class); startActivity(intent); } }); } } |
Khi chúng ta chuyển trang như vậy thì MainActivity sẽ được đẩy xuống dưới BackStack và AboutActivity được add vào đầu của BackStack. Vì vậy khi mà chúng ta nhấn back từ AboutActivity thì MainActivity được đẩy lên và vào lại onResume.
Chuyển Activity trong Android rất dễ truy nhiên bạn phải nhớ được Life Cycle (onCreate, onStart, onResume, onPause, onStop, onStart, onDestroy…) của từng Activity khi chúng ta gọi startActivity.
Lưu ý: Mọi Activity mà bạn tạo ra phải được khai báo trong file AndroidManifest.xml. Nếu bạn không khai báo mà cố tình sử dụng Activity này thì hệ thống sẽ ném ra ngoại lệ nên các bạn hết sức lưu ý. Điều này cũng được áp dụng khi các bạn sử dụng Service trong Android.
Dưới đây là hai Activity được khia báo trong AndroidManifest.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.nguyennghia.eitguide.activitydemo"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".AboutActivity"></activity> </application> </manifest> |
Tuy nhiên trong Android Studio khi bạn tạo Activity bằng cách dưới đây thì hệ thống sẽ phát sinh cho bạn hai file
- + Một file có đuôi mở rộng .java mà bạn tạo
- + Một file .xml định nghĩa UI cho activity này.
Và hệ thống tự động khai báo Activity mà bạn vừa tạo trong AndroidManifest.xml.
Để làm như vậy các bạn xem nhấn chuột phải vào bên vùng quản lý file của project. Chọn Activity > Empty Activity. Sau đó nhập tên class Activity để hệ thống tự generate cho các bạn file xml và khai báo activity này trong AndroidManifest.xml cho các bạn luôn
Chuyển đổi Activity kèm theo dữ liệu
Quay lại cái thời mới học lập trình trên mobile của tôi (Window Phone và Android), tôi tìm đến các bài viết chuyển trang trong hai nền tảng này. Ví dụ mà tôi tìm thấy trong các bài viết đó là
+ Trang bên này gồm một TextView và một Button
+ Trang bên kia gồm 1 TextView
Khi chúng ta nhấn vào buttont thì lấy ra text ở TextView bên activity này và truyền qua Activity kia. Bên activity kia sẽ lấy ra giá trị mà bên kia truyền sang và gán vào TextView của Activity. Tôi nhận thấy rằng ví dụ này rất dễ hiểu nhưng chưa đủ. Các bạn chỉ có thể truyền được String qua nhưng còn các đối tượng khác phức tạp hơn thì sao như một Array, một Object, hay truyền bất cứ thứ gì qua và truyền được nhiều thứ.
Để tạo sự khác biệt trong phần này tôi sẽ hướng dẫn các bạn truyền bất cứ thứ gì sang Activity một cách dễ dàng và linh hoạt.
Việc chuyển đối Activity có kèm theo dữ liệu cũng tương tự với trường hợp chuyển Activity không kèm theo dữ liệu nhưng có một số điểm khác sau đây:
Khi tạo Intent phải put các dữ liệu kèm theo qua đối tượng intent này. Chúng ta sử dụng các phương thức có tiền tố là put của đối tượng intent để đẩy dữ liệu, mỗi dữ liệu mà bạn put vào sẽ có 1 key đi kèm.
Intent cho chúng ta put bất cứ kiểu dữ liệu nào ví dụ như các kiểu dữ liệu nguyên thủy char, boolean, int, float, long, String hay kiểu mảng boolean[], char[], int[] và kiểu dữ liệu object tuy nhiên những kiểu dữ liệu này bạn phải implement Parcelable or Serializable.
Gửi dữ liệu đi
Gửi dữ liệu đi riêng lẻ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Intent intent = new Intent(MainActivity.this, AboutActivity.class); intent.putExtra("int_key", 4); intent.putExtra("char_key", 'r'); intent.putExtra("boolean_key", true); intent.putExtra("long_key", 323L); intent.putExtra("float_key", 3.2f); intent.putExtra("string_key", "Chuyen Activity trong Android"); intent.putExtra("double", 32D); intent.putExtra("int_array_key", new int[]{1, 2, 9}); intent.putExtra("boolean_array_key", new boolean[]{true, false, true, true}); intent.putExtra("char_array_Key", new char[] {'e', 'i', 't', 'g', 'u', 'i', 'd', 'e'}); intent.putExtra("rect_key", new Rect(0,0, 200, 200)); startActivity(intent); |
Ở trên tôi put khá nhiều kiểu dữ liệu để các bạn có thể hình dung được nhiều hơn. Chúng ta có thể truyền kiểu char, int, long, double, String, hay kiểu mảng, kiểu object.
Chú ý là các key trong các phương thức put phải khác nhau.
Gửi dữ liệu đi sử dụng Bundle
Thay vì cách sử dụng là put vào intent thì chúng ta sẽ sử dụng một đối tượng gọi là Bundle. Chúng ta sẽ put các dữ liệu vào đối tượng này và sử dụng phương thức putExtras để put “cả cục” này vào intent.
1 2 3 4 5 6 7 8 9 10 11 12 |
Bundle bundle = new Bundle(); bundle.putChar("char", 'e'); bundle.putInt("int", 3); bundle.putString("string", "wwww.eitguide.com"); bundle.putFloat("float", 5.2f); bundle.putDouble("double", 843D); bundle.putLong("long", 55343L); bundle.putParcelable("parcelable", new Rect(0, 0, 300, 300)); intent.putExtras(bundle); startActivity(intent); |
Sau khi put dữ liệu xong thì chúng ta chỉ việc gọi phương thức startActivity để thực hiện chuyển trang và truyền dữ liệu.
Nhận dữ liệu
Sau khi startActivity thì ở Activity bạn muốn chuyển sẽ có được dữ liệu mà activity kia gửi đi. Và để lấy được dữ liêu chúng ta phải làm như sau:
Lấy ra đối tượng Intent mà bên kia gửi qua bằng phương thức getIntent();
Từ đối tượng đối tượng intent có được từ getIntent() chúng ta bắt đầu lấy ra những dữ liệu trong đối tượng này bằng phương thức getXExtra. Với X là kiêu dữ liệu mà bạn muốn lấy ra. Key lấy ra phải đúng với key bạn truyền vào.
1 2 3 4 5 6 7 8 9 |
//get data from MainActivity int intValue = intent.getIntExtra("int_key", 0); char charValue = intent.getCharExtra("char_key", 'a'); float floatValue = intent.getFloatExtra("float_key", 0f); boolean booleanValue = intent.getBooleanExtra("boolean_key", false); String stringValue = intent.getStringExtra("string_key"); int[] intArrayValue = intent.getIntArrayExtra("int_array_key"); char[] charArrayValue = intent.getCharArrayExtra("char_array_key"); Rect rect = intent.getParcelableExtra("rect_key"); |
Những phương thức lấy ra dữ liệu thường có hai đối số là:
- Đối số thứ nhất là key mà bạn đã put bên activity gọi startActivity
- Đối số thứ hai là giá trị default nếu key không tồn tại
Nếu chúng ta gửi dữ liệu qua bằng Bundle thì làm như sau:
1 2 3 4 5 6 7 8 |
Bundle bundle = intent.getExtras(); char charValue = bundle.getChar("char"); int intValue = bundle.getInt("int"); String stringValue = bundle.getString("string"); float floatValue = bundle.getFloat("float"); double doubleValue = bundle.getDouble("double"); long longValue = bundle.getLong("long"); Rect rect = bundle.getParcelable("parcelable"); |
Kết luận
Trên đây tôi đã giới thiệu cho các bạn cách chuyển Activity cũng như truyền và nhận dữ liệu với Intent như thế nào. Tuy nhiên còn một trường hợp mà tôi không nói ra trong bài viết này đó là trường hợp khi chúng ta back activity về activity khác thì cách truyền dữ liệu ở trường hợp này nhứ thế nào, gợi ý cho các bạn tìm hiểu phương thức startActivityForResult và phương thức onResultActivity . Bài viết tiếp theo tôi sẽ nói về điều đó. Nếu trong bài viết có bất cứ thắc mắc nào các bạn có thể để lại bình luận ở phía dưới để được giải đáp sớm nhất.
Tks bạn, hóng bài argument trong Fragment. Chuyển dữ liệu giữa activity và fragment, fragment với fragment, fragment với activity.
Ok bạn, mình đang viết các bài về Fragment và ViewPager.
hay qua ban oi!
Xin chào bạn.Mình đang vướng mắc một vấn đề như thế này.
Mình có hai Activity, cái Activity thứ nhất mình cho hiện listview sau đó mình dùng intent truyền dữ liệu qua Activity thứ 2,Activity có chức năng counter(nhấn button để tăng giá trị).Nhưng khi kết thúc counter mình quay lại Activity thứ nhất để thực hiện lại nhưng mà bên Activity thứ hai gia tri counter không hoạt động,Mình phải quay lại thực hiện lần nửa mới được. Mình là newbie nên mong bạn giúp đở mình
post code 2 Activities của bạn lên xem sao
bài viết của anh rất hay và dễ hiểu . cảm ơn anh nhiều
Cảm ơn em.
bài viết rất hữu ích, mong bạn làm nhiều bài hướng dẫn về android. Thank you so much! I got what i wanted from your site.
Cảm ơn bạn. Hy vọng bạn sẽ ghé thăm blog để cập những bài viết mới.