You are here

Flutter là gì? Vì sao nên sử dụng Flutter

Flutter là một khái niệm khá mới mẻ trong thế giới công nghệ, Flutter hỗ trợ tạo các ứng dụng app di dộng cho nhiều hệ điều hành khác nhau. Bài viết dưới đây sẽ cập nhật thêm nhiều kiến thức thông tin về Flutter, các bạn hãy cùng tìm hiểu nhé!

1. Flutter là gì

Flutter là một SDK phát triển ứng dụng di động nguồn mở được tạo ra bởi Google. Nó được sử dụng để phát triển ứng dụng cho Android và iOS, cũng là phương thức chính để tạo ứng dụng cho Google Fuchsia.

Flutter được phát triển nhằm giải quyết bài toán thường gặp trong mobile là Fast Development và Native Performance. Nếu như React Native chỉ đảm bảo Fast Development và Code Native thuần chỉ đảm bảo Native Performance thì Flutter có thể giải quyết được cả 2 vấn đề này.

Ngôn ngữ được sử dụng trong Flutter là DART, tương tự như JavaScript, nó cũng chạy một hàng đợi sự kiện theo luồng. Lợi ích lớn nhất của việc sử dụng Flutter là nó trực tiếp tạo ra các nhị phân ARM sẽ thực thi trực tiếp trên nền tảng gốc giúp chạy nó nhanh hơn.

2. Khác biệt giữa Android và Flutter?

Chắc hẳn không ít người đang thắc mắc, chẳng phải Google đã có bộ SDK cho di động, có tên gọi Android rồi hay sao. Nhưng với Google, thế giới mobile là quá rộng chỉ với một giải pháp duy nhất là Android. Với việc ra mắt phiên bản beta 1 này, giờ đây họ có trong tay hai bộ SDK cho ứng dụng di động: Android và Flutter. Và điểm khác biệt cơ bản giữa Flutter và Android: tạo ra các ứng dụng chạy trên cả iOS và Android.

Là một bộ SDK đa nền tảng, các ứng dụng Flutter có thể hoạt động trên cả iOS và Android. Nó như một thủ thuật khôn khéo để tương thích được với framework UI trên cả hai hệ điều hành này. Các ứng dụng này không biên dịch trực tiếp với các ứng dụng native của Android và iOS.

Thay vào đó, chúng chạy trên engine render Flutter (được viết bằng C++) và Flutter Framework (được viết bằng Dart, cũng như các ứng dụng Flutter), cả hai bộ này đều được đóng gói cùng với mọi ứng dụng. Sau đó bộ SDK sẽ đóng gói lại vào trong một ứng dụng để sẵn sàng chạy trên mỗi nền tảng. Bạn tạo ra ứng dụng của mình, một engine mới sẽ chạy các đoạn code, và các đoạn code native vừa đủ để nền tảng Flutter chạy trên cả Android và iOS.

Đóng gói cả một engine đi kèm cùng ứng dụng sẽ làm cho kích thước bộ cài đặt lớn hơn hẳn. Trang Hỏi đáp của Flutter cho biết, một ứng dụng “trống” thông thường sẽ chỉ khoảng 6-7MB trên Android, vì vậy dù là ứng dụng nào, phần kích thước tăng lên cũng là rất nhiều. Nhưng lợi ích của việc này là các ứng dụng này sẽ rất nhanh.

Flutter được thiết kế từ đầu để đạt tới tốc độ khung hình 60fps. Trong khi đây không phải là một con số hiếm gặp trên iOS, nhưng với Android, bạn có thể cảm thấy sự khác biệt rõ rệt ngay lập tức. Cũng nhờ việc xuất xưởng cùng với cả một nền tảng cho ứng dụng của mình, các nhà phát triển sẽ tránh được nhiều vấn đề về sự phân mảnh của Android.

3. Tại sao nên sử dụng Flutter?

Phát triển ứng dụng nhanh chóng: Tính năng hot reload của nó giúp bạn nhanh chóng và dễ dàng thử nghiệm, xây dựng giao diện người dùng, thêm tính năng và sửa lỗi nhanh hơn. Trải nghiệm tải lại lần thứ hai, mà không làm mất trạng thái, trên emulator, simulator và device cho iOS và Android.

UI đẹp và biểu cảm: Thỏa mãn người dùng của bạn với các widget built-in đẹp mắt theo Material Design và Cupertino (iOS-flavor), các API chuyển động phong phú, scroll tự nhiên mượt mà và tự nhận thức được nền tảng.

Framework hiện đại và reactive: Dễ dàng tạo giao diện người dùng của bạn với framework hiện đại, reactive của Flutter và tập hợp các platform, layout và widget phong phú. Giải quyết các thách thức giao diện người dùng khó khăn của bạn với các API mạnh mẽ và linh hoạt cho 2D, animation, gesture, hiệu ứng và hơn thế nữa.

Truy cập các tính năng và SDK native: Làm cho ứng dụng của bạn trở nên sống động với API của platform, SDK của bên thứ ba và native code. Nó cho phép bạn sử dụng lại mã Java, Swift và ObjC hiện tại của mình và truy cập các tính năng và SDK native trên iOS và Android.

Phát triển ứng dụng thống nhất: Flutter có các công cụ và thư viện để giúp bạn dễ dàng đưa ý tưởng của mình vào cuộc sống trên iOS và Android. Nếu bạn chưa có kinh nghiệm phát triển trên thiết bị di động, thì Flutter là một cách dễ dàng và nhanh chóng để xây dựng các ứng dụng di động tuyệt đẹp. Nếu bạn là một nhà phát triển iOS hoặc Android có kinh nghiệm, bạn có thể sử dụng Flutter cho các View của bạn và tận dụng nhiều code Java / Kotlin / ObjC / Swift hiện có của bạn.

4. Flutter cho Mobile App – Flatform thật sự ấn tượng

Gần đây nhiều người quan tâm Flutter nên mình cũng đi tìm hiểu xem sao. Dù chỉ mới tìm hiểu thôi nhưng Flutter thật sự ấn tượng với Flutter với những điểm sau:

1.1 Sử dụng DART: Một ngôn ngữ lập trình hướng đối tượng do Google phát triển. DART là một static type language nên nó là AOT (Ahead of Time), compile xong hết rồi mới chạy. Trong khi đó nó cũng là JIT (Just in Time) giống như các dynamic type language. Khi dev thì nó sử dụng JIT để hỗ trợ Hot Load và build release thì dùng AOT để tối ưu hiệu năng như một native code bình thường.

1.2 Ưu điểm DART: DART cũng hướng tới việc trở thành một ngôn ngữ có thể chạy trên nhiều platform khác nhau, nó cũng có máy ảo (VM) làm nhiệm vụ dịch source code sang bytecode như Java. Hiện tại DART có thể transpile ra các ngôn ngữ khác như JS để chạy trên trình duyệt. Cái này không liên quan mobile lắm tuy nhiên đây cũng là 1 ưu điểm lớn của ngôn ngữ này nên không thể bỏ qua.

1.3 Vậy còn native module ? Khác với JS Bridge, Flutter “nói chuyện” với các native module bằng chính các native interface. Mặc dù vẫn được gọi là “bridge”, tuy nhiên nó nhanh hơn rất nhiều và gân như không bị “thắc cổ chai” như React Native. Ngoài ra các module này được kiến trúc theo “plugin”, các module viết cho Flutter phải tuân thủ các rule trong này. Cá nhân mình thấy viết native module cho Flutter rất tự nhiên, không cần phải học các syntax macro C/C++ như RN.

1.4 Flutter Engine: Có tới 4 threads (runners) được sử dụng trong app: Platform Task Runner, UI Task Runner, GPU Task Runner và IO Task Runner. Các threads này độc lập và không share memory với nhau, chúng giao tiếp với nhau thông qua channels…

1.5. Về document: Cở hữu bộ doc phải nói là không bỏ sót thứ gì. Đi từ cài đặt, hướng dẫn viết app cơ bản cho tới CI/CD, debug, test và profiling. Bộ profiling của Flutter cũng cực kì hay dùng để đo đạc các chỉ số về performance khá chi tiết.

1.6 Các ví dụ và kiến trúc ứng dụng: Có hẳn 1 repository trên Github đủ hết các example cho Redux, mvc, mvu… tha hồ quẹo lựa.

Với các đặc tính trên và tốc độ phát triển rất nhanh như hiện tại, đây sẽ là lựa chọn hàng đầu cho mobile development.

5. Hướng dẫn cài đặt Cài đặt Flutter

1.1 Yêu cầu hệ thống:

Hệ điều hành Mircrosoft Windows (64-bit).

Dung lượng trống 1.32 GB (không bao gồm dung lượng cho phần IDE/tools).

Các công cụ: Flutter phụ thuộc vào các công cụ có sẵn trong máy tính của bạn:

PowerShell 5.0 hoặc mới hơn (cái này đã được tích hợp sẵn vào Windows 10).

Nếu Git đã được cài, hãy chắc chắn rằng bạn có thể chạy câu lệnh git từ cửa sổ lệnh Windows Command Prompt hoặc PowerShell.

1.2 Tiến hành cài đặt

Bạn duyệt tìm đến phần Get the Flutter SDK, bấm vào flutter_windows_vxxxx-stable.zip (với xxxx là phiên bản flutter, ví dụ tại thời điểm mình viết Blog này là flutter_windows_v1.9.1+hotfix.6-stable.zip) để tải flutter SDK về. Bạn có thể lưu ở đâu tùy thích sau khi giải nén mình có thể di chuyển nó sau.

Sau khi tải về xong, các bạn giải nén file vừa tải về (tùy chọn Extract here) ta sẽ được một thư mục tên là flutter. Các bạn hãy để thư mục này vào một nơi nào đó mà bạn muốn (lưu ý không được đặt vào thư mục “C:\Program Files\” vì nó yêu cầu quyền riêng tư). Ví dụ mình sẽ làm y như trong docs của Google là tạo một thư mục mới tên là src đặt trong ổ đĩa “C:\” và copy thư mục flutter vào thư mục “C:\src\”.

Bây giờ bạn đã sẵn sàng để chạy lệnh Flutter Console. Nhưng để có thể chạy lệnh flutter từ Command Prompt, bạn nên cập nhật đường dẫn. Các bước thực hiện như sau:

Click phải chuột vào This PC, chọn Properties

Chọn Advanced system settings (gần phía trên bên trái) trong cửa sổ System.

Chọn Enviroment Variables… trong cửa sổ System Properties.

Trong phần User variables, các bạn tìm Variable là PATH và nhấn Edit, nhấn New và thêm đường dẫn đến thư mục “flutter\bin”. Ví dụ của mình là “C:\src\flutter\bin”. Nếu như bạn không tìm thấy Variable PATH bạn nhấn New và đặt tên Variable là PATH và đường dẫn đến thư mục flutter\bin của bạn.

Nhấn OK để lưu tất cả các thay đổi lại.

Mở System Settings

Mở cài đặt nâng cao

Mở Environment Variables

 

Thêm biến môi trường

 

Sửa biến môi trường Path

Vậy là bạn đã có thể chạy lệnh flutter từ Command Prompt rồi. Giờ hãy check thử xem nào. Mở Command Prompt lên và chạy lệnh “flutter –version”. Nếu như nó hiện lên thông tin Flutter, framwork, dart version… thì bạn đã cài thành công. Tiếp theo, chúng ta sẽ phải cài đặt Plugins cho IDE để code với Flutter.

1.3 Cài đặt Plugins Flutter

Google hỗ trợ bạn hai IDE đó là Android Studio và Visual Studio Code. Đương nhiên là bạn vẫn có thể sử dụng các IDE khác, nhưng không chắc là nó có sẵn các Plugin cho bạn dùng, và nếu có thì nó cũng là do cá nhân tự phát triển, không đầy đủ bằng. Vì vậy, các bạn nên cài đặt trên Android Studio và Visual Studio Code.

+ Đổi với Android Studio các bạn làm như sau:

- Khởi động Android Studio

- Ở màn hình Welcome to Android Studio, mở menu Configure (phía dưới góc phải), chọn Plugins

Mở Plugins trong Android Studio

- Ở tab Marketplace, các bạn search “flutter”, bạn nhấn install vào plugin Flutter ngay kết quả đầu tiên. Plugin này yêu cầu các bạn cài đặt thêm một plugin nữa là Dart, các bạn chọn Yes để cho phép cài đặt Dart nữa.

- Các bạn RESTART IDE để áp dụng thay đổi.

+ Đối với Visual Studio Code, các bạn làm như sau:

Mở Visual Studio Code

Vào tab Extentions trên thanh sidebar bên trái

Search “flutter”, các bạn nhấn Install plugin đầu tiên của kết quả tìm kiếm. Khác với Android Studio, khi cài plugin Flutter thì plugin Dart cũng sẽ được tự cài theo mà không cần bạn xác nhận.

Cài đặt extention Flutter cho VS Code

Vậy là quá trình cài đặt plugin đã xong và sẵn sàng để code với Flutter. Tiếp theo, hãy tạo một máy ảo Android nào.

1.4 Tạo máy ảo Android Studio

Để tạo một máy ảo Android Studio, các bạn làm theo các bước sau:

Khởi động Android Studio

Ảnh Open-AVD-Manager

Mở AVD Manager

Vào menu Configure và chọn AVD Manager

Chọn Create Virtual Device

Chọn một thiết bị và nhấn Next

Các bạn chọn một image x86 hoặc x86_64 đều được (khuyến khích bản mới nhất – nếu không có sẵn thì bạn nhấn Download và đợi một chút để nó tải image đó) sau đó nhấn Next
Trong phần Graphics, bạn chọn Hardware – GLES 2.0. Bạn có sửa các tùy chọn khác nếu muốn và nhấn Finish để tạo máy ảo.

Hoàn tất cấu hình và nhấn Finish

1.5 Kiểm tra và chấp nhận điều khoản

Đến đây gần như bạn đã hoàn tất, giờ hãy kiểm tra lại lần nữa nào. Bạn mở Command Prompt, gõ lệnh “flutter doctor” và nhấn enter, sau khi câu lệnh chạy xong, bạn kiểm tra xem các mục Flutter, Android toolchain, Android Studio, Connected device có được tích hay chưa, nếu chưa bạn hãy kiểm tra và thực hiện lại các bước ở trên mình đã hướng dẫn nhé.

Nếu như các bạn làm theo những gì mình đã hướng dẫn từ đầu bài viết, bạn chỉ còn một bước là hoàn thành. Ở trong Command Prompt, bạn chạy lệnh “flutter doctor –android-licenses”, sau đó, màn hình cmd sẽ hiện lên một loạt các điều khoản SDK, bạn cứ nhấn “y” và enter để đồng ý hết.

Lưu ý là bước chấp nhận điều khoản rất quan trọng, nếu như bạn không chấp nhận điều khoản SDK, khi bạn build app sẽ bị lỗi ngay và không thể build được.

Vậy là mọi thiết lập đã hoàn tất, hãy cùng tạo một project vớ Flutter và chạy thử nào!

6. Hướng dẫn lập trình app nghe nhạc online và offline sử dụng Flutter

Dưới đây là ví dụ về xây dựng một ứng dụng App nghe nhạc online và offline đơn giản.

Để làm được ứng dụng này ngoài các vấn đề cơ bản về android ví dụ như layout, listview, gridview… Bạn cần biết thêm về service, widget, media player, broadcast, notifications...

Khi xây dựng một ứng dụng bạn cần phân tích ứng dụng mình cần phát triển như thiết kế hệ thống, giao diện người dùng... Sự cần thiết tương tác người dùng và ứng dụng như yếu tố cần thiết ứng dụng cho người dùng, các điểm cần thiết người dùng có thể sử dụng nhất…

Ở nội dung bài viết này mình không thể nói chi tiết về mặt phân tích hệ thống và sự tương tác về mặt người dùng. Sau đây mình sẽ hướng dẫn về thiết kế giao diện về một ứng dụng nghe nhạc online cũng như offline khá đơn giản.

Kiến thức cơ bản về service , media player , mediaplayer broadcast, notification.

Services trong Android

Một Service là một thành phần được chạy bên trong nền để xử lý các công việc trong thời gian dài. Một ứng dụng nghe nhạc có thể phát nhạc, trong khi đó người dùng đang ở giao diện của ứng dụng khác. Hoặc ứng dụng download có thể tải dữ liệu trên mạng về máy mà không ngăn chặn người dùng tương tác với các ứng dụng khác. Một Service gồm hai trạng thái cơ bản:

Started:

Một service được gọi là started khi một thành phần của ứng dụng, chẳng hạn như là activity, start nó bằng cách gọi phương thức startService(). Mỗi lần được started, service chạy bên dưới vô thời hạn, thậm chí ngay cả khi thành phần đã started nó bị hủy.

Bound:

Một service được gọi là bound khi một thành phần ứng dụng liên kết với nó bằng cách gọi phương thức bindService(). Một dịch vụ ràng buộc cung cấp một giao diện client-server cho phép các thành phần tương tác với service, gửi yêu cầu, nhận kết quả, thậm chí tương tự trong việc giao tiếp với interprocess (IPC).

Mỗi service có tập các phương thức và bạn có thể implement để giám sát việc thay đổi các trạng thái của service, và thậm chí bạn có thể thực hiện các công việc ở mỗi trạng thái thích hợp.
Trong sơ đồ sau phía bên trái mô tả vòng đời của service khi được tạo với startService(), và phía bên phải mô tả vòng đời của service khi được tạo với bindService().

Sơ đồ mô tả vòng đời của service

Để tạo một service bạn có thể tạo một class kế thừa class Service. Class Service có nhiều phương thức callback, bạn không cần phải implement hết các phương thức này, tuy nhiên việc hiểu rõ và áp dụng chúng trong code là rất quan trọng trong việc đáp ứng yêu cầu của người dùng.

onStartCommand(): Hệ thống gọi phương thức này khi có một thành phần khác, chẳng hạn như activity, yêu cầu service đã được started, bởi gọi phương thúc startService(). Nếu bạn implement phương thức này thì bạn phải có trách nhiệm stop service khi công việc của nó đã hoàn thành, bằng cách gọi phương thức stopSelf() hoặc stopService().

onBind(): Hệ thống gọi phương thức này khi có một thành phần khác một liên kết với service bằng cách gọi phương thức bindService(). Nếu bạn implement phương thức này, thì bạn phải cung cấp một giao diện để client sử dụng giao tiếp với service, bằng cách trả về đối tượng IBinder. Bạn phải luôn implement phương thức này, tuy nhiên nếu bạn không muốn các liên kết, thì có thể trả vể null.

onUnbind(): Hệ thống gọi phương thức này khi tất cả các client đã bị ngắt kết nối từ một giao diện đặt biệt được tạo bởi các service.

onRebind(): Hệ thống gọi phương thức này khi có một client mới được kết nối với service, mà trước đó đã có thông báo rằng tất cả đã bị ngắt kết nối bởi onUnbind().
onCreate(): Hệ thống gọi phương thức này khi service được tạo lần đầu tiên bởi gọi phương thức onStartCommand() hoặc onBind().

onDestroy(): Hệ thống gọi phương thức này khi service đã không còn được sử dụng trong thời gian dài. Bạn nên gọi phương phức này để giải phóng các tài nguyên hệ thống.

Một số lưu ý khi ngắt service

Có nhiều lời gọi start nó tuy nhiên chỉ cần gọi một lần gọi stopSelf() cho service hay nói cách khác dù bạn có start service bao nhiêu lần thì chỉ cần một lời gọi stopSelf là đủ để đảm bảo service được tắt.

Liên quan tới AndroidManifest.xml

Cũng giống như intent khi bạn muốn sử dụng service trong ứng dụng của mình thì không quan khai báo nó trong file AndroidManifest.xml ít nhất là một thẻ service với một thuộc tính là android:name=”.ten__file_extend_tu_service”.

Quan Trọng

Chúng ta sẽ hay gặp hai loại Service trong android đó là Local Service và Remote Service

Local Service tức là service chỉ được truy cập trong nội bộ ứng dụng đó mà thôi, còn đối với Remote Service thì có thể cho ứng dụng khác, có thể trển các devide tương tác với nó.

Ví dụ

Ví dụ này mang đến cho bạn các bước đơn giản để tạo một service trong Android. Bạn tiến hành theo các bước sau:

package com.android.serviceexample
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class HelloService extends Service {

private static final String TAG = "HelloService";

private boolean isRunning = false;

@Override
public void onCreate() {
Log.i(TAG, "Service onCreate");

isRunning = true;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

Log.i(TAG, "Service onStartCommand");

//Creating new thread for my service
//Always write your long running tasks in a separate thread, to avoid ANR
new Thread(new Runnable() {
@Override
public void run() {

//Your logic that service will perform will be placed here
//In this example we are just looping and waits for 1000 milliseconds in each loop.
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (Exception e) {
}

if(isRunning){
Log.i(TAG, "Service running");
}
}

//Stop service once it finishes its task
stopSelf();
}
}).start();

return Service.START_STICKY;
}

@Override
public IBinder onBind(Intent arg0) {
Log.i(TAG, "Service onBind");
return null;
}

@Override
public void onDestroy() {

isRunning = false;

Log.i(TAG, "Service onDestroy");
}
}
File: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.serviceexample" >

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".HelloActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<!--Service declared in manifest -->
<service android:name=".HelloService"
android:exported="false"/>
</application>

</manifest>

Mediaplayer

Android cung cấp nhiều cách để phát lại quyền điều khiển file audio.video và âm thanh. Một trong cách này là gọi lớp MediaPlayer. Android đang cung cấp cho lớp MediaPlayer quyền truy cập được xây dựng trong các dịch vụ MediaPlayer như chơi nhạc, video,… Để sử dụng MediaPlayer, chúng ta phải gọi phương thức Create() của lớp này. Phương thức này trả về một thể hiện của lớp MediaPlayer khi lập trình android. Cú pháp như sau:MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.song);

Tham số thứ hai là tên của một bài hát mà bạn muốn nghe. Bạn phải tạo một tập tin mới trong dự án của bạn với một tên thật và đăt file nhạc trong nó.

Khi bạn đã tạo một đối tượng MediaPlayer, bạn có thể gọi phương thức để bắt đầu hoặc ngừng nhạc. Những phương thức được kiệt kê dưới đây:

mediaPlayer.start();

mediaPlayer.pause();

Trong khi gọi phương thức start(), nhạc sẽ được chơi từ khi bắt đầu.

Nếu phương thức này gọi lại sau phương thức pause(), nhạc sẽ bắt đầu chơi từ nơi mà nó tới và không từ đầu.

Để bắt đầu âm nhạc ngay từ đầu, bạn phải gọi phương thức reset(). Cú pháp của nó được đưa ra dưới đây.

mediaPlayer.reset();

Ngoài sự bắt đầu và tạm dừng phương pháp, có những phương thức khác được cung cấp bởi lớp này để đối phó tốt hơn với các file audio/video. Những phương thức này được liệt kê dưới đây:

**Phương thức và mô tả.

1.isPlaying()

Phương thức này chỉ trả về true/false cho biết bài hát được chơi hay không

2.seekTo (position)

Phương thức này có một số nguyên, và di chuyển bài hát đến giây phút đặc biệt

3.getCurrentDuration()

Phương thức này trả về vị trí hiện tại của bài hát trong mili giây

4.getDuration()

Phương thức này trả về tổng thời gian của bài hát trong mili giây

5.reset()

Phương thức này reset máy nghe nhạc phương tiện truyền thông

6.release()

Phương thức này phát hành bất kỳ tài nguyên gắn với đối tượng MediaPlayer

7.setVolume(float leftVolume, float rightVolume)

Phương thức này đặt âm lượng lên xuống cho cầu thủ này

8.setDataSource(FileDescriptor fd)

Phương thức này tập hợp các nguồn dữ liệu của tập tin âm thanh / video

9.selectTrack(int index)

Phương thức này có một số nguyên, và chọn bài hát từ danh sách trên chỉ số đặc biệt

10.getTrackInfo()

Phương thức này trả về một mảng các thông tin theo dõi

Intent.

Khái niệm về Intent:

Intent Là một miêu tả về một hoạt động cần được thực hiện. Còn nói một cách đơn giản và dễ hiểu hơn, Intent là một cơ cấu cho phép truyền thông điệp giữa các thành phần của 1 ứng dụng và giữa các ứng dụng với nhau.

Các thuộc tính của Intent:

Action:

Là hành động được thực hiện, vd : ACTION_VIEW, ACTION_MAIN

Data:

Là dữ liệu sẽ được xử lý trong action, thường được diễn tả là một Uri (Uniform Resource Identifier

VD:

ACTION_VIEW content://contacts/people/1

Hiển thị thông tin về người với mã danh 1

ACTION_DIAL content://contacts/people/1

Hiển thị màn hình gọi đến người với mã danh 1

ACTION_DIAL tel:123

Hiển thị màn hình gọi với số gọi là 123

Ngoài ra còn có 1 số thuộc tính mà ta có thể bổ sung vào Intent:

Category:

Bổ sung thêm thông tin cho action của Intent.

VD:

CATEGORY_LAUNCHER

Thông báo sẽ thêm vào Launcher như là một ứng dụng top-level

Type:

Chỉ rõ kiểu của data

Component:

Chỉ rõ thành phần sẽ nhận và xử lý intent. Khi thuộc tính này được xác định thì các thuộc tính khác sẽ trở thành thuộc tính phụ.

Extras:

mang theo đối tượng Bundle chứa các giá trị bổ sung.

VD:

ACTION_MAIN và CATEGORY_HOME: trở về màn hình Home của Android (khi bấm nút Home của di động)

Phân loại Intent:

Intent được chia làm 2 loại:Explicit Intents:

Intent đã được xác định thuộc tính component, nghĩa là đã chỉ rõ thành phần sẽ nhận và xử lý intent. Thông thường intent dạng này sẽ không bổ sung thêm các thuộc tính khác như action, data. Explicit Intent thương được sử dụng để khởi chạy các activity trong cùng 1 ứng dụng.Implicit Intents:

Intent không chỉ rõ component xử lý, thay vào đó nó bổ sung thông tin trong các thuộc tính. Khi intent được gửi đi, hệ thống sẽ dựa vào những thông tin này để quyết định component nào thích hợp nhất để xử lý nó.

VD:

ACTION_DIAL

tel:123 thông thường sẽ được hệ thống giao cho activity Phone Dialer mặc định của Android xử lý.

Một số action thường sử dụng trong Intent:

ACTION_ANSWER

Mở Activity để xử lý cuộc gọi tới, thường là Phone Dialer của Android

ACTION_CALL

Mở 1 Phone Dialer (mặc định là PD của Android) và ngay lập tức thực hiện cuộc gọi dựa vào thông tin trong data URI

ACTION_DELETE

Mở Activity cho phép xóa dữ liệu mà địa chỉ của nó chứa trong data URI

ACTION_DIAL

Mở 1 Phone Dialer (mặc định là PD của Android) và điền thông tin lấy từ địa chỉ chứa trong data URI

ACTION_EDIT

Mở 1 Activity cho phép chỉnh sửa dữ liệu mà địa chỉ lấy từ data URI

ACTION_SEND

Mở 1 Activity cho phép gửi dữ liệu lấy từ data URI, kiểu của dữ liệu xác định trong thuộc tính type

ACTION_SENDTO

Mở 1 Activity cho phép gửi thông điệp tới địa chỉ lấy từ data URI

ACTION_VIEW

Action thông dụng nhất, khởi chạy activity thích hợp để hiển thị dữ liệu trong data URI

ACTION_MAIN

Sử dụng để khởi chạy 1 Activity

BroadCast Receive on Android

Broadcast Receivers được hiểu đơn giản là nhận và xử lý các thông điệp được phát ra từ các ứng dụng khác, từ hệ thống, hoặc từ các services chạy ngầm bên trong ứng dụng gửi lên để cập nhật giao diện. Trong Broadcast Receiver có sử dụng đối tượng Intent Filter, nó giống như bộ lọc, giúp cho Receiver nhận được thông điệp và chọn đúng tác vụ để thực thi, chi tiết hơn bạn có thể tham khảo thêm tại link đính kèm.

Sau đây là ví dụ một số sự kiện Intent hệ thống cung cấp:

Android.intent.action.BATTERY_CHANGED:

Broadcast về các trạng thái của pin như: sạc, mức độ pin,…

android.intent.action.BATTERY_LOW: Cho biết tình trạng pin yếu trên thiết bị.

android.intent.action.BATTERY_OKAY: Cho biết pin đang ở tình trạng tốt sau khi ở tình trạng pin yếu.

android.intent.action.BOOT_COMPLETED: Broadcast chỉ thực hiện một lần, sau khi hệ thống hoàn thành việc khởi động. Bạn cần khai báo permission

android.permission.RECEIVE_BOOT_COMPLETED trong manifest khi dùng intent này.

android.intent.action.BUG_REPORT: Hiển thị 1 activity để báo lỗi.

android.intent.action.CAMERA_BUTTON: Người dùng nhấn vào button camera để đi đến trình quay số.

android.intent.action.DATE_CHANGED: Ngày đã được thay đổi.

android.intent.action.REBOOT: Khởi động lại thiết bị.

Có hai bước quan trọng để cho Broadcast Receivers làm việc:

Tạo Broadcast Receiver.

Đăng ký Broadcast Receiver.

Để đăng kí Broadcast Receiver, chúng ta có hai cách để thực hiện vấn đề này:

Đăng ký trong coding bằng hàm registerReceiver(BroadcastReceiver receiver, Intent filter). Cách này thường được sử dụng khi ứng dụng chỉ cần nhận thông điệp và xử lý trong khi một Activity nào đó đang sống. Lưu ý: Khi bạn đăng ký trong Activity, thì khi thoát khỏi Activity, bạn nên hủy đăng ký (unregisterReceiver(BroadcastReceiver receiver)) để tránh những xử lý ngoài ý muốn có thể gây crash ứng dụng. Thông thường, các chuyên gia khuyên bạn nên register/ unregister theo từng cặp sự kiện vòng đời của một activity như: onCreate/ onDestroy, onResume/ onPause.

Đăng ký trong Manifest: Nó trở thành dịch vụ, tự động lắng nghe mọi thứ trong Intent – filter (kể cả khi đã đóng ứng dụng). Trong trường hợp bạn muốn tự phát ra và gửi các intents tùy chỉnh riêng từ ứng dụng của bạn thì bạn làm thêm một bước nữa là phải tạo và Broadcast các intents này bằng cách sử dụng phương thức sendBroadcast()/ sendStickyBroadcast (Intent) của class activity.

-----------
1. Creating the BroadcastReceive on Android.

public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Intent Detected.", Toast.LENGTH_LONG).show();
}
}

2. Registering Broadcast Receiver

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name="MyReceiver">

<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED">
</action>
</intent-filter>

</receiver>
</application>

**Xây dựng layout mainmenu **

1. Get list nhạc trong máy.

2. Giao diện music chạy nhạc.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/desktop_background2"
android:orientation="vertical">

<RelativeLayout
android:id="@+id/rl_bottom_view"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:background="@drawable/top_layout_bg"
android:orientation="horizontal">

<ImageView
android:id="@+id/list_show_album"
android:layout_width="54dp"
android:layout_height="60dp"
android:layout_centerVertical="true"
android:layout_margin="3dp"
android:adjustViewBounds="true"
android:background="@drawable/detail_pic_bg"
android:minHeight="60dp"
android:minWidth="60dp"
android:paddingTop="4dp"
android:scaleType="centerInside"
android:src="@drawable/default_bg_s" />

<LinearLayout
android:id="@+id/ll_01"
android:layout_width="100dp"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@+id/list_show_album"
android:gravity="center_vertical"
android:orientation="vertical">

<TextView
android:id="@+id/list_song_name"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:text="Song name:"
android:textColor="@color/fashion_color"
android:textStyle="bold" />

<TextView
android:id="@+id/list_song_durction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00:00--00:00"
android:textColor="@color/fashion_color" />
</LinearLayout>

<ViewFlipper
android:id="@+id/my_flipper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/ll_01">

<LinearLayout
android:id="@+id/control"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingBottom="2dp">

<ImageButton
android:id="@+id/btnPrevious_player"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@null"
android:scaleType="fitCenter"
android:src="@drawable/desktop_prevbt" />

<ImageButton
android:id="@+id/btnPlay_player"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@null"
android:scaleType="fitCenter"
android:src="@drawable/desktop_playbt" />

<ImageButton
android:id="@+id/btnNext_player"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@null"
android:scaleType="fitCenter"
android:src="@drawable/desktop_nextbt" />
</LinearLayout>

<LinearLayout
android:id="@+id/ll_choose_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:gravity="center_vertical|right"
android:orientation="horizontal">

<ImageView
android:id="@+id/move_to_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/move2group" />
</LinearLayout>
</ViewFlipper>

<ProgressBar
android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="fill_parent"
android:layout_height="4dp"
android:layout_alignParentTop="true"
android:progressDrawable="@drawable/progress_dotted" />
</RelativeLayout>

<android.support.v4.view.ViewPager
android:id="@+id/center_body_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/rl_bottom_view"
android:layout_below="@+id/actionbar"></android.support.v4.view.ViewPager>

</RelativeLayout>

Giao diện máy khi lấy ra dự liệu

Đến đây bạn đã hiểu thế nào chứ? Vì sao nên sử dụng Flutter?

Cảm ơn! Chúc các bạn thành công!