Service
什麼是Service?
Service是Android四大組件之一,它能夠在後臺執行一些比較耗時較長的操作,並且不提供用戶界面。應用場景:後臺播放音樂等。簡單理解爲沒有界面的Activity。
Service的創建
繼承Service類並重寫bind方法,並在Manifest.xml中註冊。
Service的兩種啓用方式
- (1)startService方式
- (2)bindService方式
Service的生命週期
使用Service完成計算案例
代碼部分:
part1:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="0dp"
android:layout_height="50dp"
android:onClick="showLocal"
android:text="演示本地廣播"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
效果圖:
LocalBroadcast.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
/**
* 用於演示本地廣播
*/
public class LocalBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "接收到了本地廣播", Toast.LENGTH_SHORT).show();
}
}
activity_local.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LocalActivity">
<Button
android:id="@+id/button2"
android:layout_width="0dp"
android:layout_height="50dp"
android:onClick="sendBroadcast"
android:text="發送廣播"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_color"
android:layout_width="0dp"
android:layout_height="50dp"
android:onClick="jumpNext"
android:text="按鈕"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button2" />
</androidx.constraintlayout.widget.ConstraintLayout>
效果圖:
activity_next.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".NextActivity">
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="changeColor"
android:text="改變顏色"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/et_color"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="58dp"
android:ems="10"
android:hint="請輸入顏色"
android:inputType="textPersonName"
app:layout_constraintBottom_toTopOf="@+id/button3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
效果圖:
NextActivity.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
/**
* 演示發送廣播更改上一頁按鈕顏色
*/
public class NextActivity extends AppCompatActivity {
private EditText et_color;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_next);
et_color = findViewById(R.id.et_color);
}
/**
* 更改顏色按鈕
* @param view
*/
public void changeColor(View view) {
// 1.發送廣播
Intent intent = new Intent("day14.local.color");
String color = et_color.getText().toString().trim();
intent.putExtra("color", color);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
// 2.關閉界面
finish();
}
}
LocalActivity.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class LocalActivity extends AppCompatActivity {
/*
* 廣播的使用步驟:
* 1.創建廣播
* 2.註冊廣播和取消註冊廣播
* 3.發送廣播
* */
private LocalBroadcast localBroadcast;
private ColorBroadcast colorBroadcast;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_local);
// 獲取按鈕
button = findViewById(R.id.btn_color);
// 註冊廣播
localBroadcast = new LocalBroadcast();
IntentFilter filter = new IntentFilter("day14.local.broadcast");
LocalBroadcastManager.getInstance(this).registerReceiver(localBroadcast, filter);
colorBroadcast = new ColorBroadcast();
IntentFilter colorFilter = new IntentFilter("day14.local.color");
LocalBroadcastManager.getInstance(this).registerReceiver(colorBroadcast, colorFilter);
}
// 取消廣播位置需要注意時機
// @Override
// protected void onPause() {
// super.onPause();
// LocalBroadcastManager.getInstance(this).unregisterReceiver(colorBroadcast);
// Log.i("LocalActivity","廣播已取消註冊");
// }
@Override
protected void onDestroy() {
super.onDestroy();
// 取消廣播註冊
LocalBroadcastManager.getInstance(this).unregisterReceiver(localBroadcast);
// LocalBroadcastManager.getInstance(this).unregisterReceiver(colorBroadcast);
}
/**
* 發送廣播
* @param view
*/
public void sendBroadcast(View view) {
Intent intent = new Intent("day14.local.broadcast");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
/**
* 演示通過廣播進行按鈕顏色更改
*/
public void jumpNext(View view) {
// 1.拿到按鈕 2.定義更改按鈕的廣播 3.註冊和取消註冊廣播 4.發送廣播
Intent intent = new Intent(this, NextActivity.class);
startActivity(intent);
}
/**
* 更改按鈕顏色的廣播(內部類)
*/
class ColorBroadcast extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String color = intent.getStringExtra("color"); // #FFFFFF
button.setBackgroundColor(Color.parseColor("#"+color));
}
}
}
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 演示本地廣播
* @param view
*/
public void showLocal(View view) {
Intent intent = new Intent(this, LocalActivity.class);
startActivity(intent);
}
}
效果圖:
點擊發送廣播
點擊按鈕
part2:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="0dp"
android:layout_height="50dp"
android:onClick="showLocal"
android:text="演示本地廣播"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:onClick="showService"
android:text="演示service"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />
</androidx.constraintlayout.widget.ConstraintLayout>
效果圖:
MyService.java
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
/**
* Service使用startService啓用的時候:onCreate方法只調用一次,
* 在銷燬之前,再次調用startService,只會觸發onStartCommand
*/
public class MyService extends Service {
private static final String TAG = "MyService";
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG,"MyService正在onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "MyService正在onDestroy");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 執行service業務的方法
Log.i(TAG, "MyService正在onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
MyService2.java
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
public class MyService2 extends Service {
private static final String TAG = "MyService2";
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG,"bindService方式啓用Service正在onCreate");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG,"bindService方式啓用Service正在onDestroy");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG,"bindService方式啓用Service正在onBind");
return null;
}
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG,"bindService方式啓用Service正在onUnbind");
return super.onUnbind(intent);
}
}
AndroidMainfest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.day14">
<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=".ServiceActivity"></activity>
<activity android:name=".NextActivity" />
<activity android:name=".LocalActivity" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <!-- service註冊 -->
<service android:name=".MyService" />
<service android:name=".MyService2" />
</application>
</manifest>
activity_service.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ServiceActivity">
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="59dp"
android:layout_marginLeft="59dp"
android:layout_marginTop="108dp"
android:onClick="startService"
android:text="啓動Service"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="104dp"
android:layout_marginEnd="57dp"
android:layout_marginRight="57dp"
android:onClick="stopService"
android:text="停止Service"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="57dp"
android:layout_marginLeft="57dp"
android:onClick="bindStart"
android:text="bind方式啓用"
app:layout_constraintBaseline_toBaselineOf="@+id/button8"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/button8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="262dp"
android:layout_marginEnd="60dp"
android:layout_marginRight="60dp"
android:onClick="unBindService"
android:text="取消綁定"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
效果圖:
ServiceActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
public class ServiceActivity extends AppCompatActivity {
private ServiceConnection serviceConnection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_service);
serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 鏈接完成後
}
@Override
public void onServiceDisconnected(ComponentName name) {
// 當結束鏈接後
}
};
}
/**
* 開是Service
* @param view
*/
public void startService(View view) {
Intent intent = new Intent(this, MyService.class);
startService(intent);
}
/**
* 結束Service
* @param view
*/
public void stopService(View view) {
Intent intent = new Intent(this, MyService.class);
stopService(intent);
}
/**
* 綁定service啓動
* @param view
*/
public void bindStart(View view) {
Intent intent = new Intent(this, MyService2.class);
bindService(intent, serviceConnection, BIND_AUTO_CREATE);
}
/**
* 取消綁定service
* @param view
*/
public void unBindService(View view) {
unbindService(serviceConnection);
}
}
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 演示本地廣播
* @param view
*/
public void showLocal(View view) {
Intent intent = new Intent(this, LocalActivity.class);
startActivity(intent);
}
/**
* 演示service
* @param view
*/
public void showService(View view) {
Intent intent = new Intent(this, ServiceActivity.class);
startActivity(intent);
}
}
效果圖:
點擊啓動SERVICE
點擊停止SERVICE
BIND方式啓用
取消綁定
part3:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="0dp"
android:layout_height="50dp"
android:onClick="showLocal"
android:text="演示本地廣播"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:onClick="showService"
android:text="演示service"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />
<Button
android:id="@+id/button9"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:onClick="showDownload"
android:text="演示模擬下載"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button4" />
</androidx.constraintlayout.widget.ConstraintLayout>
效果圖:
DownloadService.java
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
public class DownloadService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 執行邏輯
int percent = intent.getIntExtra("percent", 0); // 下載百分比
while(true) {
percent++;
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (percent == 100) {
// 1.發起通知,告訴其他下載完成
LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent("day14.download"));
// 跳出循環
break;
}
}
// 2.結束Service
stopSelf();
return START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
DownloadBroadcast.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class DownloadBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "下載完成", Toast.LENGTH_SHORT).show();
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.day14">
<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=".ServiceActivity" />
<activity android:name=".NextActivity" />
<activity android:name=".LocalActivity" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <!-- service註冊 -->
<service android:name=".MyService" />
<service android:name=".MyService2" />
<service android:name=".DownloadService" />
</application>
</manifest>
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
private DownloadBroadcast downloadBroadcast;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 註冊廣播
downloadBroadcast = new DownloadBroadcast();
IntentFilter intentFilter = new IntentFilter("day14.download");
LocalBroadcastManager.getInstance(this).registerReceiver(downloadBroadcast, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(downloadBroadcast);
}
/**
* 演示本地廣播
* @param view
*/
public void showLocal(View view) {
Intent intent = new Intent(this, LocalActivity.class);
startActivity(intent);
}
/**
* 演示service
* @param view
*/
public void showService(View view) {
Intent intent = new Intent(this, ServiceActivity.class);
startActivity(intent);
}
/**
* 演示下載案例
* @param view
*/
public void showDownload(View view) {
/*
* 點擊下載模擬按鈕,啓用一個Service,傳遞下載進度,每隔幾毫秒,下載進度+1,
* 直到100,提示下載完成並結束service
* */
//1.創建service 2.完成service中不斷加1的方法 3.發起廣播 4.創建廣播並註冊廣播、註銷廣播
Intent intent = new Intent(this, DownloadService.class);
intent.putExtra("percent", 0);
startService(intent);
}
}
效果圖:
part4:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button"
android:layout_width="0dp"
android:layout_height="50dp"
android:onClick="showLocal"
android:text="演示本地廣播"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:onClick="showService"
android:text="演示service"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button" />
<Button
android:id="@+id/button9"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:onClick="showDownload"
android:text="演示模擬下載"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button4" />
<Button
android:id="@+id/button10"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:onClick="showCompute"
android:text="演示計算數據"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button9" />
</androidx.constraintlayout.widget.ConstraintLayout>
效果圖:
activity_compute.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ComputeActivity">
<EditText
android:id="@+id/et_math"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="55dp"
android:ems="10"
android:hint="請輸入數學成績"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/et_chinese"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="47dp"
android:ems="10"
android:hint="請輸入語文成績"
android:inputType="textPersonName"
app:layout_constraintStart_toStartOf="@+id/et_math"
app:layout_constraintTop_toBottomOf="@+id/et_math" />
<TextView
android:id="@+id/tv_avg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="26dp"
android:layout_marginEnd="14dp"
android:layout_marginRight="14dp"
app:layout_constraintEnd_toEndOf="@+id/button11"
app:layout_constraintTop_toBottomOf="@+id/et_chinese" />
<Button
android:id="@+id/button11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="33dp"
android:onClick="submit"
android:text="確定"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tv_avg" />
</androidx.constraintlayout.widget.ConstraintLayout>
效果圖:
ComputeService.java
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import androidx.annotation.Nullable;
public class ComputeService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
public double caculate(double math, double chinese) {
double result = (math+chinese)/2;
return result;
}
class MyBinder extends Binder{
public ComputeService getService() {
return ComputeService.this;
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.day14">
<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=".ComputeActivity"></activity>
<activity android:name=".ServiceActivity" />
<activity android:name=".NextActivity" />
<activity android:name=".LocalActivity" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <!-- service註冊 -->
<service android:name=".MyService" />
<service android:name=".MyService2" />
<service android:name=".DownloadService" />
<service android:name=".ComputeService" />
</application>
</manifest>
ComputeActivity.java
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class ComputeActivity extends AppCompatActivity {
private ServiceConnection serviceConnection;
private ComputeService.MyBinder myBinder;
private EditText et_math;
private EditText et_chinese;
private TextView tx_avg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_compute);
// 視圖控件
et_math = findViewById(R.id.et_math);
et_chinese = findViewById(R.id.et_chinese);
tx_avg = findViewById(R.id.tv_avg);
serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder = (ComputeService.MyBinder) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
Intent intent = new Intent(this, ComputeService.class);
bindService(intent,serviceConnection, BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(serviceConnection);
}
/**
* 確定計算
* @param view
*/
public void submit(View view) {
String math = et_math.getText().toString();
String chinese = et_chinese.getText().toString();
ComputeService computeService = myBinder.getService();
double result = computeService.caculate(Double.parseDouble(math), Double.parseDouble(chinese));
tx_avg.setText(result+"");
}
}
MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
private DownloadBroadcast downloadBroadcast;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 註冊廣播
downloadBroadcast = new DownloadBroadcast();
IntentFilter intentFilter = new IntentFilter("day14.download");
LocalBroadcastManager.getInstance(this).registerReceiver(downloadBroadcast, intentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(this).unregisterReceiver(downloadBroadcast);
}
/**
* 演示本地廣播
* @param view
*/
public void showLocal(View view) {
Intent intent = new Intent(this, LocalActivity.class);
startActivity(intent);
}
/**
* 演示service
* @param view
*/
public void showService(View view) {
Intent intent = new Intent(this, ServiceActivity.class);
startActivity(intent);
}
/**
* 演示下載案例
* @param view
*/
public void showDownload(View view) {
/*
* 點擊下載模擬按鈕,啓用一個Service,傳遞下載進度,每隔幾毫秒,下載進度+1,
* 直到100,提示下載完成並結束service
* */
//1.創建service 2.完成service中不斷加1的方法 3.發起廣播 4.創建廣播並註冊廣播、註銷廣播
Intent intent = new Intent(this, DownloadService.class);
intent.putExtra("percent", 0);
startService(intent);
}
/**
* 計算
* @param view
*/
public void showCompute(View view) {
startActivity(new Intent(this, ComputeActivity.class));
}
}
效果圖: