• Save
Android Nâng Cao-Bài 1: Service And Toast
Upcoming SlideShare
Loading in...5
×
 

Android Nâng Cao-Bài 1: Service And Toast

on

  • 2,089 views

Khoá học Android Nâng Cao có 9 bài tất cả. Đây là bài số 1.

Khoá học Android Nâng Cao có 9 bài tất cả. Đây là bài số 1.

Statistics

Views

Total Views
2,089
Views on SlideShare
1,956
Embed Views
133

Actions

Likes
8
Downloads
0
Comments
0

4 Embeds 133

http://folami.nghelong.com 129
http://9033734_6243fc73a0af92aad1d4f418a065e081c8a59a3b.blogspot.com 2
http://webcache.googleusercontent.com 1
https://www.linkedin.com 1

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • If the package is declared in the aidl file isn&apos;t same as its folder path. The compiler will be show an error message. <br />

Android Nâng Cao-Bài 1: Service And Toast Android Nâng Cao-Bài 1: Service And Toast Presentation Transcript

  • ANDROID NÂNG CAO Bài 1: Service & Toast
  • Service là gì? ● ● Là cơ chế xử lý công việc ở thread khác với Activity thread (UI thread). Không ngắt ngang luồng xử lý của UI thread khi có một công việc xen ngang. Activity  Activity   Service  ♫ ♫ Không dùng Service Dùng Service
  • Các loại service ● Trong Android có hai loại service: ● Unbound service (Started service) ● Bound service View slide
  • Vòng đời của service startService() onCreate() onCreate() onStartCommand() Service stop bởi service hoặc client bindService() onBind() Service Running Active Lifetime Service Running onUnbind() onDestroy() Service Shutdown Unbound Service onDestroy() Service Shutdown Bound Service Client gọi unbindService() View slide
  • Hiện thực Unbound Service ● Tạo service ● Đăng ký trong AndroidManifest.xml ● ● Sử dụng phương thức startService() để start service. Sử dụng phương thức stopService() để stop service
  • Tạo Service ● ● ● Tạo lớp kế thừa từ lớp Service. Hiện thực phương thức onBind: Trả về null vì ở đây là unbound service. Hiện thức các phương thức callback: onCreate, onStartComand, onDestroy nếu cần thiết.
  • Tạo Service import android.app.Service; import android.content.Intent; import android.os.IBinder; public class SampleService extends Service { @Override public IBinder onBind(Intent arg0) { return null; } } @Override public void onCreate() {      Log.d(“SampleService", "onCreate"); } @Override public int onStartCommand(Intent intent, int flags, int startId) {  Thread t = new Thread() {   @Override   public void run() {        try {          Thread.sleep(1000);          } catch (InterruptedException e) {           Log.d("SampleService", e.toString());          }         }       };       t.start(); return START_STICKY; } @Override public void onDestroy() {      Log.d(“SampleService", "onDestroy"); }
  • Đăng ký trong AndroidManifest.xml 1.Mở file AndroidManifest.xml chọn “Application” tab 2.Click nút “Add” ở mục “Application Nodes” 2 1
  • Đăng ký trong AndroidManifest.xml 3.Chọn “Service” rồi nhấn nút “OK”. ※ Trong trường hợp cursor đang nằm trong ô nhập liệu thì dòng “Create a new element in the selected element, ...”, chọn lại dòng trên ※ 3
  • Đăng ký trong AndroidManifest.xml 4.Kiểm tra là bạn đang chọn “Service” trong “Application Nodes”. Nhập tên của service bạn muốn đăng ký vào “Name”. Nhấn vào nút “Browse”, giúp bạn tìm ra tên service cầnnhập vào dễ dàng hơn 4
  • Start Service ● ● Tạo đối tượng Intent. Sử dụng phương thức Context#startService để start service. Intent intent = new Intent(this, SampleService.class); startService(intent);
  • Bài tập 01 ● Thiết kế chương trình có một màn hình + 1 service. ● Màn hình có một nút “Start” và nút “Stop”. – – ● Nhấn vào nút “Start” thì start service. Nhấn vào nút “Stop” thì stop service. Service in log ra logcat mỗi 1 giây.
  • Bind Service ● Bind service ● Gọi các phương thức do service cung cấp. ● Get và set dữ liệu cho service. ● Sử dụng ServiceConnection interface.
  • RMI Registry Publish Get Client Server IDL
  • Start Binding A Service Phía Client 1. Gọi bindService() để kết nối đến service. 2. bindService() return ngay lập tức (bất đồng bộ). 3. Khi kết nối giữa client và service được tạo, hệ thống sẽ gọi phương thức onServiceConnected() ở phía client và truyền IBinder instance cho client để client dùng để giao tiếp với service. Phía Server 1. Khi client đầu tiên bind vào service, hệ thống gọi phương thức onBind() để lấy IBinder instance một lần . 2. IBinder instance này được dùng cho tất cả các kết nối từ các client khác.
  • Stop Binding Service ● Khi client cuối cùng gọi phương thức unbindService() để ngắt kết nối với service (unbind), hệ thống sẽ huỷ bỏ service.
  • Hiện thực IBinder ● Có ba phương pháp sau: ● Extend lớp Binder. ● Sử dụng Messenger. ● Sử dụng AIDL.
  • Extend Lớp Binder ● Phương pháp này chỉ dùng cho local & private client (client & server cùng process và cùng ứng dụng) Phía Client 1.Gọi bindService() để kết nối service. 2.Lấy đối tượng IBinder từ onServiceConnected(). 3.Gọi các public method do server cung cấp để thực hiện các yệu cầu nghiệp vụ Phía Server 1.Trong phương thức onBind(), tạo đối tượng Binder theo 1 trong 3 cách sau: ● Đối tượng có các public methods → client có thể sử dụng. ● Đối tượng có getter return instance của chính service → client có thể sử dụng các public method của service. ● Đối tượng có getter return một instance của lớp khác thuộc service→ client có thể sử dụng các public method của lớp này. 2.Return đối tượng Binder.
  • Extend Lớp Binder: Phía Server 1.mBinder return cho hệ thống.Đối tượng này được dùng để gửi đến các client qua onServiceConnected() 2.Return cho client, client dùng Ibinder này để gọi public method getService() và lấy con trỏ đến đối tượng service 3.Sau khi có refence đến đối tượng service, client có thể gọi phương thức sampleMethod() để thực hiện nghiệp vụ public class SampleLocalService extends Service { // Binder gui den client private final IBinder mBinder = new SampleLocalBinder(); @Override public IBinder onBind(Intent intent) { return mBinder; } /** * Lop hien thuc lop Binder. Do service va client thuc thi cung process * va ung dung nen khong quan tam den IPC. */ public class SampleLocalBinder extends Binder { SampleLocalService getService() { // Return chinh instance cua service, client goi public method. return SampleLocalService.this; } } //Sample public method ma client co the goi public void sampleMethod() { //Thuc hien nghiep vu nao do. } }
  • Extend Lớp Binder: Phía Client public class SampleActivity extends Activity { SampleLocalService mService; boolean mIsBound = false; 1.Gọi bindService() với Intent hợp lí sẽ bind vào service và onBind() callback trên server sẽ được gọi. Instance của anonymous class sẽ định nghĩa slide sau @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected void onStart() { super.onStart(); // Bind vào SampleLocalService Intent intent = new Intent(this, SampleLocalService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); // Unbind với service if (mIsBound) { unbindService(mConnection); mIsBound = false; } }
  • Extend Lớp Binder: Phía Client 2. Lớp anonymous, gọi một lần ở 1. nó tạo ra đối tượng và các hàm callback. 3.Khi nút được ấn cần kiểm tra service đã bind chưa. Nếu đã bind gọi public method của service //Định nghĩa các callback khi service bind, truyền cho bindService() private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName className,IBinder service) { // SampleLocalService vừa bind, cast IBinder và nhận reference đến //SampleLocalService SampleLocalBinder binder = (SampleLocalBinder) service; mService = binder.getService(); mIsBound = true; } @Override public void onServiceDisconnected(ComponentName arg0) { mIsBound = false; } }; //Được gọi khi nút được nhấn. public void onButtonClick(View v) { if (mIsBound) { // Gọi phương thức của SampleLocalService.Lời gọi này đôi khi làm cho chương //trình bị treo.Do đó nên thực hiện lời gọi này ở thread khác. mService.sampleMethod(); }}}
  • Extend Lớp Binder: Biểu đồ Tuần tự
  • Sử dụng Messenger ● Phương pháp này phù hợp cho trường hợp client và server khác process (IPC) Phía Client 1.Gọi bindService() để kết nối service trong onStart() hoặc onCreate(). 2.Định nghĩa lớp ServiceConnection với onServiceConnected() callback. 3.Khi nhận được IBinder thì khởi tạo Messenger. 4.Sử dụng Messenger để trao đổi thông tin giữa client & server Phía Server 1.Định nghĩa message handler. 2.Tạo đối tượng của lớp Messanger với message handler đã tạo ở bước 1. 3.Return IBinder của đối tượng Messenger ở bước 2 cho phía client trong phương thức onBind().
  • Sử dụng Messenger: Phía Server public class SampleService extends Service { //Khai báo mã câu lệnh để server thực hiện nghiệp vụ nào đó static final int MSG_SAMPLE_COMMAND = 1; 1.Hiện thực lớp MyIncommingHandler kế thừa lớp Handler để xử lý tất cả các thông điệp nhận được từ phía client trong phương thức handleMessage() //Trình xử lý các câu lệnh nhận được từ phía client. class MyIncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_SAMPLE_COMMAND: //Thực hiện một nghiệp vụ nào đó. break; default: super.handleMessage(msg); } } }
  • Sử dụng Messenger: Phía Server 2. Tạo đối tượng mMessenger (Messenger) có trình xử lý thông điệp xây dựng ở bước 1. Tất cả các thông điệp gửi qua Messenger này đều gửi đến MyInCommingHandler. /** * Thông điệp gửi đến MyIncomingHandler . */ final Messenger mMessenger = new Messenger(new MyIncomingHandler()); /** * Khi service được bide, interface của messenger được return về cho client * tạo ra kênh để client cò thể gửi thông điệp đến server. */ @Override public IBinder onBind(Intent intent) { return mMessenger.getBinder(); } } 3. Sử dụng phương thức getBinder() của lớp Messenger để lấy reference đến đối tượng IBinder và return về cho phía client.
  • Sử dụng Messenger: Phía Client 1.Hiện thực một anonymous class từ ServiceConnection interface. Trong đó có phương thức onServiceConnected được gọi khi service được bind và Ibinder được truyền vào qua thông số. Sử dụng Ibinder để tạo đối tượng Messenger. public class SampleActivity extends Activity { //Messenger dùng để trao đổi thông điệp với service Messenger mService = null; //Cờ để đánh dấu là service đã bind chưa. boolean mIsBound = false; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { //Phương thức này được gọi khi service được bind thành công. //IBinder được truyền vào qua tham số của phương thức. //Chúng ta sử dụng IBinder này để tạo đối tượng Messenger. mService = new Messenger(service); mIsBound = true; } public void onServiceDisconnected(ComponentName className) { //Phương thức này được gọi khi kết nối bị đứt bất thường như //process chết. mService = null; mIsBound = false; } };
  • Sử dụng Messenger: Phía Client public void doCommand(View v) { if (!mIsBound) return; // Tạo thông điệp và gửi đến service Message msg = Message.obtain(null, SampleService.MSG_SAMPLE_COMMAND, 0, 0); try { mService.send(msg); } catch (RemoteException e) { e.printStackTrace(); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); 2.Mỗi khi phương thức setContentView(R.layout.main); doCommand() được gọi, sử } dụng phương thức obtain của lớp Message để tạo ra đối tượng Message. Sử dụng các giá trị định nghĩa trong what lớp SampleService. Sau đó sử dụng đối tượng mService tạo ra ở bước 1 để gửi thông điệp đến service
  • Sử dụng Messenger: Phía Client @Override protected void onStart() { super.onStart(); // Bind service bindService(new Intent(this, SampleService.class), mConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); // Unbind service if (mIsBound) { unbindService(mConnection); mIsBound = false; } } } 3.Mỗi khi Activity start & resume thì service được bind bằng cách dùng phương thức bindService với mConnection tạo ra ở bước 1.
  • Sử dụng Messenger: Biểu đồ Tuần tự
  • Sử dụng AIDL ● ● Phương pháp này rất ít gặp trong thực tế vì chỉ phù hợp với các ứng dụng đa luồng, hiện thực khá phức tạp. Tập tin AIDL là gì? ● ● ● ● ● Tập tin định nghĩa interface cho các phương thức được hiện thực trong service có thể truy xuất từ xa. Tập tin AIDL có phần mở rộng là aidl. Tập tin này được đặt cùng thư mục các tập tin mã nguồn khác. Eclipse sẽ tự động biên dịch tập tin này sang tập tin Java tương ứng. Trong tập tin này interface Stub được tạo ra. Sử dụng interface này để giao tiếp giữa client và server. Các kiểu sau đây hay các Array của các kiểu sau đây là hợp lệ dùng trong AIDL: Kiểu cơ bản, String, Parcelable, List, Map, AIDL interface
  • Sử dụng AIDL ● Tạo AIDL file: ● Chọn vào thư mục tương ứng với package name của interface sinh ra từ file AIDL và nhấn chuột phải chọn New > File (Xem hình)
  • Sử dụng AIDL ● ● Định nghĩa các phương thức trong interface: package com.example.aidlsampleservice; interface IMySampleService{ void doSomething(); } Tập tin Java tương ứng tự động sinh ra:
  • Sử dụng AIDL ● Interface IMySampleService.Stub được sinh ra: public interface IMySampleService extends android.os.IInterface { /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.example.aidlsampleservice.IMySampleService { … public static com.example.aidlsampleservice.IMySampleService asInterface(android.os.IBinder obj) { … public void doSomething() throws android.os.RemoteException; }
  • Sử dụng AIDL Phía Client 1.Gọi bindService() để kết nối service trong onStart() hoặc onCreate(). 2.Định nghĩa lớp ServiceConnection với onServiceConnected() callback. Khi nhận được IBinder thì khởi tạo IMySampleService sử dụng phương thức asInterface của Stub. 3.Sử dụng các phương thức trong IMySampleService để trao đổi với server. Phía Server 1.Tạo đối tượng binder từ lớp nội hiện thực Stub interface. 2.Return binder được tạo ở bước 1 cho phía client trong phương thức onBind().
  • Sử dụng AIDL Step 1 ● Phía Server: Step 2 public class AIDLSampleService extends Service { // Dinh nghia service Stub private IMySampleService.Stub binder = new IMySampleService.Stub(){ public void doSomething(){ //Nội dung cần thực hiện } } @Override public IBinder onBind(Intent intent) { return binder; } }
  • Sử dụng AIDL ● Phía Client: private IMySampleService mService; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { mService = null; } @Override public void onServiceConnected(ComponentName name, IBinder binder) { mService = IMySampleService.Stub.asInterface(binder); } };
  • Bài tập 02 ● Hiện thực lại Bài tập 01 sử dụng 3 kỹ thuật hiện thực bound service.
  • Toast ● Toast là gì? ● Sử dụng Toast ● Customize Toast ● Lưu ý về bảo mật khi dùng Toast
  • Toast là gì? ● ● ● Dùng để trình bày một thông điệp lên màn hình trong thời gian ngắn. Người dùng không thể tương tác với Toast vì Toast không bao giờ được focus. Toast thường được dùng với những thành phần không có GUI như service, thread, ...
  • Sử dụng Toast ● Android cung cấp hai phương thức sau đây để tạo đối tượng Toast public static Toast makeText (Context context, CharSequence text, int duration) public static Toast makeText (Context context, int resId, int duration) ● context: context để trình bày Toast ● text (resId): Thông điệp cần trình bày. ● duration: Một trong hai giá trị: – – ● Toast.LENGTH_LONG Toast.LENGTH_SHORT Sử dụng Toast#show để trình bày Toast lên màn Toast.makeText(this,R.string.testtoast, Toast.LENGTH_LONG).show() hình.Ví dụ:
  • Customize Toast ● Toast cho phép customize 2 thuộc tính: ● Vị trí hiển thị. ● View.
  • Customize Toast ● Thay đổi vị trí hiển thị: ● Sử dụng phương thức: public void setGravity(int gravity, int xOffset, int yOffset) ● Chúng ta có thể sử dụng phép toán bit_or (|) để kết nối các hằng sau đây cho tham số gravity: – – – ● CENTER CENTER_HORIZONTAL CENTER_VERTICAL Thay đổi View: ● Sử dụng phương thức: public void setView(View view) ● Có thể sử dụng LayoutInflater để inflate từ xml layout file
  • Bài tập 03 ● Hiện thực Toast mô tả trong hình ở Slide “Customize Toast”
  • Lưu ý Bảo mật ● Xem video clip về TapJacking. ● Khi lập trình cần: ● ● Có cơ chế bảo vệ tường minh cho các View nhạy cảm như nút “Mua hàng”, “Chuyển tiền”, “Chấp nhận”, … Đối với các control lớn cần override phương thức: public boolean onFilterTouchEventForSecurity (MotionEvent event)
  • Nguyen Huu Phuoc, MEng. ●  Blog:http://folami.nghelong.com ●  Website http://phuocnh.nghelong.com