Android开发学习笔记整理(15)-BroadcastReceive和Service

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));
    }
    
}

效果图:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章