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));
}
}
效果图: