ก่อนเข้าตัวอย่าง เราควรรู้ว่า Service ใน Android คืออะไร Service จะทำ Background Operation โดยไม่โต้ตอบกับ UI และทำงานต่อแม้ Activity ถูก Destroy
ตัวอย่างนี้สาธิตวิธีสร้าง Android Service ที่ Dalvik จะไม่ Kill
Step 1 - สร้าง Project ใหม่ใน Android Studio ไปที่ File → New Project และกรอกรายละเอียดทั้งหมดเพื่อสร้าง Project ใหม่
Step 2 - เพิ่มโค้ดต่อไปนี้ใน res/layout/activity_main.xml
<?xml version = "1.0" encoding = "utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android = "https://schemas.android.com/apk/res/android" xmlns:app = "https://schemas.android.com/apk/res-auto" xmlns:tools = "https://schemas.android.com/tools" android:layout_width = "match_parent" android:layout_height = "match_parent" tools:context = ".MainActivity"> <TextView android:id = "@+id/text" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Start Service" android:textSize = "25sp" app:layout_constraintBottom_toBottomOf = "parent" app:layout_constraintLeft_toLeftOf = "parent" app:layout_constraintRight_toRightOf = "parent" app:layout_constraintTop_toTopOf = "parent" /> </android.support.constraint.ConstraintLayout>
ในโค้ดข้างต้นเราใช้ TextView เมื่อ User คลิกที่ TextView จะ Start Service และ Stop Service
Step 3 - เพิ่มโค้ดต่อไปนี้ใน src/MainActivity.java
package com.example.andy.myapplication; import android.app.ActivityManager; import android.content.Context; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.TextView; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final TextView text = findViewById(R.id.text); text.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (isMyServiceRunning(service.class)) { text.setText("Stopped"); stopService(new Intent(MainActivity.this, service.class)); } else { text.setText("Started"); startService(new Intent(MainActivity.this, service.class)); } } }); } private boolean isMyServiceRunning(Class<?> serviceClass) { ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { if (serviceClass.getName().equals(service.service.getClassName())) { return true; } } return false; } }ในโค้ดข้างต้นเพื่อ Start และ Stop Service เราใช้ Intent และส่ง Context และ Service Class ตอนนี้สร้าง Service Class ใน Package Folder เป็น service.class และเพิ่มโค้ดต่อไปนี้
package com.example.andy.myapplication; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Context; import android.content.Intent; import android.graphics.Color; import android.media.MediaPlayer; import android.os.Build; import android.os.IBinder; import android.os.PowerManager; import android.support.annotation.RequiresApi; import android.support.v4.app.NotificationCompat; import android.util.Log; import android.widget.Toast; public class service extends Service { PowerManager pm; @SuppressLint("InvalidWakeLockTag") PowerManager.WakeLock wl; @Override public IBinder onBind(Intent intent) { return null; } @SuppressLint("InvalidWakeLockTag") @Override public void onCreate() { super.onCreate(); pm = (PowerManager) getSystemService(Context.POWER_SERVICE); wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag"); } @TargetApi(Build.VERSION_CODES.O) @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) @Override public int onStartCommand(Intent intent, int flags, int startId) { wl.acquire(); //Do some task Toast.makeText(this, "Notification Service started by user.", Toast.LENGTH_LONG).show(); return START_STICKY; } @RequiresApi(api = Build.VERSION_CODES.N) @Override public void onDestroy() { super.onDestroy(); wl.release(); Toast.makeText(this, "Notification Service destroyed by user.", Toast.LENGTH_LONG).show(); } }ในโค้ดข้างต้นเราเรียก Power Manager เพื่อป้องกัน Screen Lock ดังนั้น Android Thread จะไม่หยุด Service Thread ดังนี้
@SuppressLint("InvalidWakeLockTag") @Override public void onCreate() { super.onCreate(); pm = (PowerManager) getSystemService(Context.POWER_SERVICE); wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "My Tag"); } @TargetApi(Build.VERSION_CODES.O) @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) @Override public int onStartCommand(Intent intent, int flags, int startId) { wl.acquire(); //Do some task Toast.makeText(this, "Notification Service started by user.", Toast.LENGTH_LONG).show(); return START_STICKY; } @RequiresApi(api = Build.VERSION_CODES.N) @Override public void onDestroy() { super.onDestroy(); wl.release(); Toast.makeText(this, "Notification Service destroyed by user.", Toast.LENGTH_LONG).show(); }Step 4 - เพิ่มโค้ดต่อไปนี้ใน manifest.xml
<?xml version = "1.0" encoding = "utf-8"?> <manifest xmlns:android = "https://schemas.android.com/apk/res/android" package = "com.example.andy.myapplication"> <uses-permission android:name = "android.permission.WAKE_LOCK"/> <application android:allowBackup = "true" android:icon = "@mipmap/ic_launcher" android:label = "@string/app_name" android:roundIcon = "@mipmap/ic_launcher_round" 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> <service android:name = ".service"/> </application> </manifest>
ลองรันแอปพลิเคชันของคุณ สมมติว่าคุณเชื่อม Android Device จริงกับคอมพิวเตอร์แล้ว เพื่อรันแอปจาก Android Studio ให้เปิดไฟล์ Activity ของโปรเจกต์และคลิกไอคอน Run จาก Toolbar เลือก Mobile Device ของคุณเป็นตัวเลือก และตรวจสอบ Mobile Device ซึ่งจะแสดงหน้าจอ Default

ในผลลัพธ์ข้างต้นเป็นหน้าจอเริ่มต้น คลิกที่ TextView จะเริ่ม Notification Service ดังนี้

ในผลลัพธ์ข้างต้น Service เริ่มต้นแล้ว ตอนนี้คลิกที่ TextView จะหยุด Notification Service ดังนี้
