Service高级

本文深入探讨了Android中的Service,重点关注了前台服务Foreground Service的定义、使用场景及实现步骤,并对比介绍了IntentService的优势和局限,包括如何通过IntentService进行网络请求和广播通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一:前台服务Foreground Service

1.什么是前台服务

前台服务是那些被认为用户知道(用户所认可的)且在系统内存不足的时候不允许系统杀死的服务。前台服务必须给状态栏提供一个通知,它被放到正在运行(Ongoing)标题之下——这就意味着通知只有在这个服务被终止或从前台主动移除通知后才能被解除。

2.为什么使用

在一般情况下,Service几乎都是在后台运行,一直默默地做着辛苦的工作。但这种情况下,后台运行的Service系统优先级相对较低,当系统内存不足时,在后台运行的Service就有可能被回收。
那么,如果我们希望Service可以一直保持运行状态且不会在内存不足的情况下被回收时,可以选择将需要保持运行的Service设置为前台服务。

3.如何实现

本文按照做音乐播放器的思路,做一下相关的说明,如何使用前台服务。
(1)首先要创建一个服务:

public class MyService extends Service {

    private static final String TAG = "MyService";

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate: ");
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand: ");
        Notification.Builder builder = new Notification.Builder(this.getApplicationContext());
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setContentTitle("标题");
        builder.setContentText("内容");
        Notification build = builder.build();
        startForeground(110,builder.build());
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "onBind: ");
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopForeground(true);
    }
}

(2)在完成Notification通知消息的构建后,在Service的onStartCommand中可以使用startForeground方法来让Android服务运行在前台

// 参数一:唯一的通知标识;参数二:通知消息。
startForeground(110, notification);// 开始前台服务

(3)如果需要停止前台服务,可以使用stopForeground来停止正在运行的前台服务。

@Override
public void onDestroy() {
    super.onDestroy();
    stopForeground(true);
}

(4)Activity代码

public class MainActivity extends AppCompatActivity {

    private Intent intent;

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

    public void onClick(View view) {
        int id = view.getId();
        switch (id){
            case R.id.startService_id:
                intent = new Intent(MainActivity.this, MyService.class);
                startService(intent);
                break;
            case R.id.stopService_id:
                stopService(intent);
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        stopService(intent);
    }
}

二:IntentService

1.IntentService介绍

IntenetService,可以看做是Service和HandlerThread的结合体,在完成了使命之后会自动停止,适合需要在工作线程处理UI无关任务的场景。

IntentService是继承自Service并处理异步请求的一个类,在IntentService内有一个工作线程在处理耗时操作

当任务执行完后,IntentService会自动停止,不需要我们去手动结束。

如果启动IntentService多次,那么每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,依次去执行,使用串行的方式,执行完自动结束。

2.IntentService的优点:不用开启线程

3.IntentService的缺点:使用广播向activity传值

4.案例:使用IntentService网络请求json串,将json串使用广播发送给activity界面

思路:创建服务,注册服务
创建服务:MyIntentService.java

public class MyIntentService extends IntentService {

    private String path = "http://www.qubaobei.com/ios/cf/dish_list.php?stage_id=1&limit=20&page=1";

    public MyIntentService(String name) {
        super(name);
    }
    //注意:必须提供无参数构造,不然清单文件中注册报错
    public MyIntentService() {
        super("MyIntentService");
    }

    //将所有耗时操作都在该方法中完成,相当于开启线程
    @Override
    protected void onHandleIntent(@androidx.annotation.Nullable Intent intent) {
        HttpUtils httpUtils = new HttpUtils();
        String string = httpUtils.getString(path);
        //向Activity或Fragment发送json串
        Intent intent1 = new Intent();
        intent1.setAction("com.jia.intentservice");
        Bundle bundle = new Bundle();
        bundle.putString("json",string);
        intent1.putExtras(bundle);
        sendBroadcast(intent1);
    }
}
public class HttpUtils {
    public String getString(String path){
        StringBuffer sb = new StringBuffer();
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        try {
            URL url = new URL(path);
            connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            connection.connect();
            if (connection.getResponseCode()==200){
                inputStream = connection.getInputStream();
                byte[] bys = new byte[1024];
                int len = 0;
                while ((len = inputStream.read(bys))!=-1){
                    sb.append(new String(bys,0,len));
                }
                return sb.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (inputStream!=null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection!=null){
                connection.disconnect();
            }
        }
        return null;
    }
}

清单文件注册服务

<service android:name=".Intentservice.MyIntentService" />

Activity代码

public class MainActivity extends AppCompatActivity {

    private MyReceiver myReceiver;
    private Intent intent;
    private ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = findViewById(R.id.listView_id);
        //动态注册广播
        myReceiver = new MyReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("com.jia.intentservice");
        registerReceiver(myReceiver,intentFilter);
        //开启服务
        intent = new Intent(this, MyIntentService.class);
        startService(intent);
        initListView();
    }

    private void initListView() {

    }

    //解除广播+关闭服务
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(myReceiver);
        stopService(intent);
    }
}

MyReceiver代码

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action.equals("com.jia.intentservice")){
            Bundle bundle = intent.getExtras();
            String json = bundle.getString("json", "");
            //接续json串 展现在ListView 中
            Toast.makeText(context, ""+json, Toast.LENGTH_SHORT).show();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值