如何使用startService

如何使用startService

情境

如何使用Service這裡講到,
使用Service可以避免memory leak以及延長Thread的生命週期,
因此要這邊要寫一個範例來示範怎麼使用startService。

程式碼說明

首先我們定義兩個Button, 一個是用啟動Service,一個是用來關閉Service,

public class MainActivity extends AppCompatActivity {
    private Button startService;
    private Button stopService;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }
    private void init(){
        final Intent intent = new Intent();
        startService = (Button) findViewById(R.id.start_service);
        stopService = (Button) findViewById(R.id.stop_service);
        startService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Bundle b = new Bundle();
                b.putBoolean("flag", true);
                intent.putExtras(b);
                intent.setClass(MainActivity.this, MyService.class);
                startService(intent);
            }
        });
        stopService.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopService(intent);
            }
        });
    }
}

接著我們寫一個類別繼承於Service,這時候會覆寫onBind方法,
由於是使用startService方式去啟動, 因此這個方法內的回傳值就會是null。
在service內, 其實我們執行在main thread內,
所以要啟動一個thread來另外計算我們的值,
透過Log把i的值印出來。

public class MyService extends Service {
    private boolean flag;
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        flag = intent.getExtras().getBoolean("flag");
        new Thread(new Runnable(){
            int i = 0;
            @Override
            public void run() {
                while(flag){
                    i++;
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.e("", i + "");
                }
            }
        }).start();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        flag = false;
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}
<service android:name=".MyService"
    android:enabled="true"
    android:exported="true" >
</service>

記得將service寫進Androidmanifest.xml內。




當呼叫stopService的時候, 他會來call onDestory,
因此只要在這個方法內把flag設為false,
則可以將thread優雅的停止。

E/        (18345): flag:true
E/        (18345): 1
E/        (18345): 2
E/        (18345): 3
E/        (18345): 4
E/        (18345): 5
E/        (18345): 6
E/        (18345): 7
E/        (18345): 8
E/        (18345): 9
E/        (18345): 10

程式碼