欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android App开发学习第十二天:service

程序员文章站 2022-03-22 09:52:53
什么是Service能够在后台长时间运行,并且没有用户界面的应用程序组件。Service的分类StartedService:通过Activity调用startService(),启动ServiceBoundService:通过Activity调用bindService(),启动后,当activity停止则service停止service的基本用法1.创建与配置package com.example;import android.app.ActivityManager;import a...

什么是Service

能够在后台长时间运行,并且没有用户界面的应用程序组件。
Service的分类
StartedService:
通过Activity调用startService(),启动Service
BoundService:
通过Activity调用bindService(),启动后,当activity停止则service停止

service的基本用法

1.创建与配置

package com.example;

import android.app.ActivityManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

import java.util.ArrayList;

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                int i = 0;
                while(isRunning()){//如果Service正在运行
                    Log.i("Service",String.valueOf(++i));
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
        }).start();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
    //判断service是否正在运行
    public boolean isRunning(){
        ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        //获取所有正在运行的Service
        ArrayList<ActivityManager.RunningServiceInfo> runningService = (ArrayList<ActivityManager.RunningServiceInfo>);
        for (int i = 0; i < runningService.size(); i++) {
            if (runningService.service.getClassName.toString.equals("com.example.MyService"))
                return true;
        }
        return false;
    }
}

2.启动和停止
启动Service:startService()
停止Service
1.由Service调用stopSelf()停止
2.由其他组件调用stopService()停止

Started Service的生命周期
Android App开发学习第十二天:service

调用startService()->onCreate()->onStartCommand()->Service运行中->
stopSelf()或stopService()->停止Service->onDestroy()->Service被关闭

package com.example;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button1 = findViewById(R.id.btn_start);
        final  Intent intent = new Intent(MainActivity.this,MyService.class);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startService(intent);

            }
        });
        Button button2 = findViewById(R.id.btn_stop);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                    stopService(intent);
            }
        });

    }
}

使用service实现音乐的播放和停止

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="horizontal"
    tools:context=".MainActivity">

   <Button
       android:id="@+id/btn_start"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="播放音乐"/>


</LinearLayout>
package com.example;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.util.Log;

import java.util.ArrayList;

public class MyService extends Service {
    static boolean isplay;//记录当前的播放状态
    MediaPlayer player;
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        //创建MediaPlayer对象,并加载播放的音频文件
//        player = MediaPlayer.create(this,R.raw.music);
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (!player.isPlaying()){
            player.start();//播放音乐
            isplay = player.isPlaying();//设置当前状态为正在播放音乐
        }
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        player.stop();//停止音乐的播放
        isplay = player.isPlaying();//设置当前状态为停止播放音乐
        player.release();//释放资源
        super.onDestroy();
    }

}
package com.example;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button1 = findViewById(R.id.btn_start);
        final  Intent intent = new Intent(MainActivity.this,MyService.class);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //启动和停止MusicService
                if (MyService.isplay == false){
                    startService(intent);//启动service
                    button1.setText("停止播放音乐");
                }else {
                    stopService(intent);//停止service
                    button1.setText("启动播放音乐");
                }

            }
        });
        Button button2 = findViewById(R.id.btn_stop);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                    stopService(intent);
            }
        });

    }

    @Override
    protected void onStart() {
        startService(new Intent(MainActivity.this,MyService.class));//启动service
        super.onStart();
    }
}

BoundService

Bound Service的生命周期
Android App开发学习第十二天:service
实现Bound Service的基本步骤
1.创建内部内类MyBinder继承Binder类,并创建getService()方法返回service
2.在Service中的onBind()方法中返回IBinder对象,即返回创建的内部类MyBinder
3.在Activity中实例化ServiceConnection对象,并重写其onServiceConnected(),onServiceDisconnected()方法,
在绑定成功后回调onServiceConnected()方法,获取service对象。
4.在Activity的onStart()方法中使用bindService()方法绑定service
5.在Acitivity的onStop()方法中使用unbindService()方法解绑service

使用Bound Service 实现模拟双色球彩票的随机选号

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/bg2"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="机选号码"
        android:textColor="#BE2020"
        android:textSize="26sp"
        android:layout_gravity="center"
        android:gravity="center"
        android:layout_marginTop="50dp"/>



    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp">

        <TextView
            android:id="@+id/tv_1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#CC0D0D" />

        <TextView
            android:id="@+id/tv_2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#CC0D0D"
            android:layout_marginLeft="5dp"/>

        <TextView
            android:id="@+id/tv_3"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#CC0D0D"
            android:layout_marginLeft="5dp"/>

        <TextView
            android:id="@+id/tv_4"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#CC0D0D"
            android:layout_marginLeft="5dp"/>

        <TextView
            android:id="@+id/tv_5"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#CC0D0D"
            android:layout_marginLeft="5dp"/>

        <TextView
            android:id="@+id/tv_6"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#CC0D0D"
            android:layout_marginLeft="5dp"/>

        <TextView
            android:id="@+id/tv_7"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="#CC0D0D"
            android:layout_marginLeft="5dp"/>
    </LinearLayout>

    <Button
        android:id="@+id/btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="随机选号"
        android:background="#DF2121"/>

</LinearLayout>
package com.example;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class BinderService extends Service {
    public BinderService() {
    }
    //创建MyBinder内部类
    public class MyBinder extends Binder{
        public BinderService getService(){//创建获取Service的方法
            return BinderService.this;//返回当前的Service类

        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return new MyBinder();//返回MyBinder  Service对象
    }
    //自定义方法,用于生成随机数
    public List getRandomNumber(){
        List resArr = new ArrayList();
        String strNumber = "";//用与保存生成的随机数
        for (int i = 0; i < 7; i++) {
            int number  = new Random().nextInt(33)+1;//生成指定范围的随机整数
            if (number<10){
                strNumber = "0" + String.valueOf(number);
            }else {
                strNumber = String.valueOf(number);
            }
            resArr.add(strNumber);//把转换后的字符串添加到Liset集合中
        }
        return resArr;
    }

    @Override
    public void onDestroy() {//销毁service
        super.onDestroy();
    }
}

package com.example;

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.Button;
import android.widget.TextView;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    BinderService binderService;//声明Service类的对象
    int[] tvid = {R.id.tv_1,R.id.tv_2,R.id.tv_3,R.id.tv_4,R.id.tv_5,R.id.tv_6,R.id.tv_7};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btn_random  = findViewById(R.id.btn);//获取随机选号按钮

        btn_random.setOnClickListener(new View.OnClickListener() {//单击按钮,获取随机彩票号码
            @Override
            public void onClick(View v) {
                List number = binderService.getRandomNumber();
                for (int i = 0; i < number.size(); i++) {
                    TextView tv = findViewById(tvid[i]);//获取文本框组件
                    tv.setText(number.get(i).toString());//显示生成的随机号码
                }
            }
        });
    }
    //创建serviceConnection对象
    private ServiceConnection conn = new ServiceConnection() {
        //连接成功回调此方法
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            binderService = ((BinderService.MyBinder)service).getService();//获取后台Service
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onStart() {
        super.onStart();
        Intent intent = new Intent(MainActivity.this, BinderService.class);
        bindService(intent,conn,BIND_AUTO_CREATE);//第三个参数可以设置绑定成功后是否自动创建service
    }

    @Override
    protected void onStop() {
        super.onStop();
        unbindService(conn);
    }
}

IntentService的基本用法

为什么要使用IntentService
Service无法自动开启线程来执行耗时任务和自动停止服务,而IntentService可以。

package com.example;

import android.app.IntentService;
import android.content.Intent;
import android.content.Context;
import android.util.Log;

/**
 * An {@link IntentService} subclass for handling asynchronous task requests in
 * a service on a separate handler thread.
 * <p>
 * TODO: Customize class - update intent actions, extra parameters and static
 * helper methods.
 */
public class MyIntentService extends IntentService {
    // TODO: Rename actions, choose action names that describe tasks that this
    // IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS
    private static final String ACTION_FOO = "com.example.action.FOO";
    private static final String ACTION_BAZ = "com.example.action.BAZ";

    // TODO: Rename parameters
    private static final String EXTRA_PARAM1 = "com.example.extra.PARAM1";
    private static final String EXTRA_PARAM2 = "com.example.extra.PARAM2";

    public MyIntentService() {
        super("MyIntentService");
    }

    /**
     * Starts this service to perform action Foo with the given parameters. If
     * the service is already performing a task this action will be queued.
     *
     * @see IntentService
     */
    // TODO: Customize helper method
    public static void startActionFoo(Context context, String param1, String param2) {
        Intent intent = new Intent(context, MyIntentService.class);
        intent.setAction(ACTION_FOO);
        intent.putExtra(EXTRA_PARAM1, param1);
        intent.putExtra(EXTRA_PARAM2, param2);
        context.startService(intent);
    }

    /**
     * Starts this service to perform action Baz with the given parameters. If
     * the service is already performing a task this action will be queued.
     *
     * @see IntentService
     */
    // TODO: Customize helper method
    public static void startActionBaz(Context context, String param1, String param2) {
        Intent intent = new Intent(context, MyIntentService.class);
        intent.setAction(ACTION_BAZ);
        intent.putExtra(EXTRA_PARAM1, param1);
        intent.putExtra(EXTRA_PARAM2, param2);
        context.startService(intent);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i("IntentService:","Service已启动");
        long endTime  = System.currentTimeMillis()+20*1000;//结束时间
        while(System.currentTimeMillis()<endTime){
            synchronized (this){
                try {
                    wait(endTime-System.currentTimeMillis());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void onDestroy() {
        Log.i("IntentService:","Service已停止");
        super.onDestroy();
    }

    /**
     * Handle action Foo in the provided background thread with the provided
     * parameters.
     */
    private void handleActionFoo(String param1, String param2) {
        // TODO: Handle action Foo
        throw new UnsupportedOperationException("Not yet implemented");
    }

    /**
     * Handle action Baz in the provided background thread with the provided
     * parameters.
     */
    private void handleActionBaz(String param1, String param2) {
        // TODO: Handle action Baz
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

package com.example;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button2 = findViewById(R.id.btn_2);
       
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startService(new Intent(MainActivity.this,MyIntentService.class));
            }
        });
    }
}

本文地址:https://blog.csdn.net/NikerunZoo/article/details/109627265