Có những loại intent nào trong android?
Intents là một thành phần quan trọng trong android. Nó cho phép các thành phần ứng dụng có thể yêu cầu các hàm từ các thành phần ứng dụng android khác. Ví dụ một activity có thể chạy một activity khác ở bên ngoài để chụp ảnh. Show Intents là một objects của android.content.Intent. Intents sẽ được gửi đến hệ thống android để xác định hành động bạn muốn thực hiện, đối tượng bạn muốn xử lý. Intents có thể bao gồm dữ liệu thông qua Bundle. Bundle giống như một cái hộp. Bên nhận sẽ mở bundle ra nhờ key và lấy ra dữ liệu Để chạy một activity, broadcast receivers , sử dụng phương thức startActivity(intent). Phương thức này được định nghĩa trong đối tượng context. Xem ví dụ dưới đây Intent i = new Intent(this, ActivityTow.class); startActivity(i);Android intents thường được sử dụng chính:
Các loại intent Có 2 loại intent trong Android: implicit và explicit. Đối tượng dữ liệu trong Intent Đối tượng dữ liệu của Intent là một cấu trúc dữ liệu được dùng bởi các component trong ứng dụng hoặc hệ thống nhận được và có những xử lý thích hợp. Đối tượng dữ liệu của Intent có thể chứa các thuộc tính sau dựa vào cách mà các component muốn tương tác hoặc thực hiện một tác vụ thích hợp: Các thuộc tính chính
Các thuộc tính tùy chọn
Intent Filter là gì? Activity, Service và BroadCast Receiver sử dụng Intent Filter để thông báo cho hệ thống biết các dạng Implicit Intent mà nó có thể xử lý. Nói cách khác, Intent Filter là bộ lọc Intent, chỉ cho những Intent được phép đi qua nó. Intent Filter mô tả khả năng của component định nghĩa nó. Khi hệ thống bắt được 1 Implicit Intent (chỉ chứa 1 số thông tin chung chung về action, data và category...), nó sẽ sử dụng những thông tin trong Intent này, kiểm tra đối chiếu với Intent Filter của các component các ứng dụng, sau đó quyết định khởi chạy ứng dụng nào thích hợp nhất để xử lý Intent bắt được. Nếu có 2 hay nhiều hơn ứng dụng thích hợp, người dùng sẽ được lựa chọn ứng dụng mình muốn. Ví dụ chúng ta thiết lập 1 Activity với bộ lọc Intent cho phép bắt và xử lý các Intent gửi SMS. Hãy lưu ý từ khóa android:scheme="sms"
Ở các bài CÁC THÀNH PHẦN GIAO DIỆN CƠ BẢN, chúng ta đã cùng nhau tìm hiểu về:
Và ở bài học hôm nay, chúng ta sẽ cùng tìm hiểu về Intent và Manifest. Do tính chất của 2 khái niệm này dày đặc lý thuyết, ít hình vẽ (ít chứ không phải không có), mình sẽ cố gắng đưa ra nhiều hình minh họa nhất có thể. Bù lại, nội dung của bài khá ngắn, dễ đọc. Nội dungĐể đọc hiểu bài này tốt nhất các bạn nên có kiến thức cơ bản về các phần:
Trong bài học này, chúng ta sẽ cùng tìm hiểu các vấn đề:
Truyền thuyết về IntentNgày xửa ngày xưa, khi chế tạo ra Android, các nhà khoa học đã nghĩ về một hình thức truyền dữ liệu giữa các màn hình (Activity), tiến trình ngầm (Service) hay các Broadcast Receiver. Nếu như trong lập trình iOS hay Windows Phone, chúng ta muốn nhập một ký tự bất kỳ ở màn hình thứ nhất, nhấn nút, sang màn hình thứ 2 hiển thị đúng ký tự đó thì:
Thì trong Android, mọi thứ hoàn toàn khác: Những dữ liệu được đưa vào một đối tượng thuộc lớp Bundle. Và đối tượng bundle này được chứa trong Intent. Ví dụ: Ở một màn hình A, bạn kích hoạt chức năng chụp ảnh (tức là màn hình B), chụp xong bạn lấy ảnh về màn hình A. Lúc này Intent chính là:
Sau đây là các trường hợp chúng ta có thể sử dụng Intent. Các trường hợp này trong quá trình làm việc bây giờ lẫn về sau, các bạn sẽ sử dụng rất thường xuyên: Đơn giản là để khởi chạy một activity khácĐể chuyển sang một Activity B từ Activity A, các bạn gọi phương thức startActivity(intent) của Activity đó. Quay trở lại với Project HelloWorld mà chúng ta đã làm từ bài 1 đến bài 4 trước đó. Lần này ta sẽ tạo một Activity mới và thực hành:
Trong file activity_main.xml, xóa hết các thành phần bên trong FrameLayout, chỉ để lại một Button với code như sau: activity_main.xml Và trong file Java tương ứng, gọi ra phương thức startActivity. Code đầy đủ như sau: MainActivity.java public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button testButton = (Button) findViewById(R.id.btnClickMe); testButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MainActivity.this, SecondActivity.class); startActivity(intent); } }); } }
Sử dụng Intent để khởi chạy ServicesServices là một loại hoạt động ngầm trong Android. Để khởi chạy Services, tương tự như trên, ta gọi đến phương thức startService(Intent). Service là một thành phần của ứng dụng, đại diện cho ứng dụng để làm một tác vụ dài hơi, mà không tương tác trực tiếp với người dùng (ví dụ như khi download một file dung lượng lớn từ internet). Service cũng có thể được dùng để hỗ trợ các ứng dụng khác. Chi tiết về Service, chúng ta sẽ nói rõ hơn trong bài Service. Sau đây chúng ta sẽ tạo một Service bù nhìn để minh họa cho Intent nhé. Bước 1: Tạo một class có tên ServiceExample và kế thừa lớp Service. Trình soạn thảo code sẽ báo lỗi, là do chúng ta chưa override hàm onBind của Service. Chúng ta sẽ sửa code thành: package com.howkteam.helloworld; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.support.annotation.Nullable; public class ExampleService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return null; } }Và thế là lỗi sẽ biến mất. Bước 2: Service cũng có vòng đời gần như Activity, nên nó cũng có hàm onCreate để override. Chúng ta sẽ override hàm này để kiểm chứng sự tồn tại của Service: package com.howkteam.helloworld; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.support.annotation.Nullable; import android.util.Log; public class ExampleService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); Log.e("Kteam", "Service da duoc khoi tao"); } }Do đặc thù của Service: Nó là thành phần chạy không có giao diện nên khi đóng app lại, Service vẫn còn nguyên gây lãng phí bộ nhớ không cần thiết. Do vậy ta sẽ hủy nó ngay khi được tạo, và ở công đoạn bị hủy (onDestroy), chúng ta đặt thêm một log nữa. package com.howkteam.helloworld; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.support.annotation.Nullable; import android.util.Log; public class ExampleService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); Log.e("Kteam", "Service da duoc khoi tao"); this.stopSelf(); } @Override public void onDestroy() { super.onDestroy(); Log.e("Kteam", "Service da duoc huy"); } }Và cuối cùng, tạo Intent trong MainActivity và khởi chạy: package com.howkteam.helloworld; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent serviceIntent = new Intent(this, ExampleService.class); startService(serviceIntent); } }Bước 3: Khai báo Service trong AndroidManifest, tương tự như Activity. Vì là Service đơn giản nên việc khai báo cũng vô cùng đơn giản: Và cùng check kết quả, chú ý chọn đúng máy ảo và tiến trình như những vùng khoanh đỏ: Tạo và gửi đi Intent dạng explicit hoặc implicitTrước tiên chúng ta cần hiểu về 2 loại Intent trong Android:
Với Intent Explicit, chúng ta đã có ví dụ ở trên (Đơn giản chỉ là khởi chạy một Activity khác). Với Intent Implicit, chúng ta làm một ví dụ nhỏ, cũng không cần sửa đổi gì nhiều, chỉ cần chỉnh code lại ở file MainActivity.java một chút: package com.howkteam.helloworld; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button testButton = (Button) findViewById(R.id.btnClickMe); testButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("http://howkteam.com/")); startActivity(i); } }); } }Run app , và bấm nút Click me, chúng ta sẽ thấy: Tại sao?
Truyền dữ liệu giữa các ActivityMột Intent có thể chứa thêm dữ liệu phụ. Các dữ liệu này được chứa trong đối tượng của lớp Bundle, có thể lấy ra được bằng phương thức getExtras(). Các dữ liệu trong Bundle được lưu dạng giống như Map (key-value). Key luôn là String, còn value thuộc kiểu dữ liệu nguyên thủy (primitive types) hoặc có các kiểu String, Bundle, Parcelable, Serializable. Phía bên Activity nhận sẽ lấy thông tin này ra bằng phương thức getAction() hoặc getData() của đối tượng Intent. Đối tượng Intent được lấy ra bằng phương thức getIntent(). Thành phần nhận dữ liệu sẽ gọi ra phương thức getIntent().getExtras() để lấy dữ liệu ra. Ví dụ: Bundle extras = getIntent().getExtras(); String data = extras.getString(Intent.EXTRA_TEXT);Một activity có thể được đóng lại bằng cách nhấn nút Back trên điện thoại. Trong trường hợp này, phương thức finish() sẽ được gọi ra. Nếu activity được khởi tạo bằng phương thức startActivity(Intent) thì bên activity gọi sẽ không yêu cầu dữ liệu trả về. Mặt khác, nếu như activity thứ hai được khởi tạo bằng phương thức startActivityForResult() thì dữ liệu có thể sẽ được trả về nhờ tham số resultCode đầu vào. Và để lấy dữ liệu ra, chúng ta override phương thức onActivityResult() của activity đang làm việc. Và tất nhiên phương thức này sẽ có tham số resultCode đầu vào để biết được acitivity nào đã gọi đến nó trước đó:
Code đầy đủ của SecondActivity.java sẽ là: package com.howkteam.helloworld; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; public class SecondActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); finish(); } @Override public void finish() { Intent data = new Intent(); data.putExtra("returnKey1", "Gia tri tra ve thu nhat. "); data.putExtra("returnKey2", "Gia tri tra ve thu hai. "); setResult(RESULT_OK, data); super.finish(); } }
Code đầy đủ của MainActivity.java package com.howkteam.helloworld; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button testButton = (Button) findViewById(R.id.btnClickMe); testButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Test khoi tao activity co du lieu tra ve Intent i = new Intent(MainActivity.this, SecondActivity.class); i.putExtra("Value1", "Gia tri thu nhat "); i.putExtra("Value2", "Gia tri thu hai "); int REQUEST_CODE = 9; startActivityForResult(i, REQUEST_CODE); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK && requestCode == 9) { if (data.hasExtra("returnKey1")) { Toast.makeText(this, data.getExtras().getString("returnKey1"), Toast.LENGTH_SHORT).show(); } } } }Do SecondActivity kết thúc rất nhanh (hàm finish được gọi ngay onCreate) nên chúng ta sẽ chỉ nhìn thấy thông báo như sau: ManifestMọi ứng dụng đều bắt buộc phải có một file AndroidManifest.xml ở thư mục gốc. AndroidManifest cung cấp thông tin cơ bản của ứng dụng cho hệ điều hành Android ví dụ như:
Một file AndroidManifest.xml sẽ có dạng cơ bản như sau, giả sử với ứng dụng HelloWorld đang làm: Chúng ta dễ thấy: Ứng dụng có activity MainActivity là activity vào đầu tiên sau khi chạy app nhờ thuộc tính android:name = “android.intent.action.MAIN”. Và không có quyền truy cập gì đặc biệt vì không có thẻ Kết luậnQua bài này chúng ta đã nắm được cơ bản về Intent – luồng dữ liệu động giúp truyền thông tin giữa các màn hình và Manifest – file liệt kê các thành phần ứng dụng. Đây là 2 phần tối cơ bản của bất kỳ ứng dụng Android nào. Bài sau chúng ta sẽ tìm hiểu về VÒNG ĐỜI CỦA MỘT ACTIVITY nhé. Sẽ có một câu đố nhỏ để giúp các bạn nắm chắc hơn (có lời giải, yên tâm). Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của mình để phát triển bài viết tốt hơn. Đừng quên “Luyện tập – Thử thách – Không ngại khó”. Thảo luậnNếu bạn có bất kỳ khó khăn hay thắc mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần bên dưới hoặc trong mục HỎI & ĐÁP trên thư viện Howkteam.com để nhận được sự hỗ trợ từ cộng đồng. |