IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android第一行代码——第十章探究服务 -> 正文阅读

[移动开发]Android第一行代码——第十章探究服务

Android 多线程

线程的基本用法

Android多线程和java多线程基本都使用相同的语法,下面展示两种写法

class MyThread extends Thread{
	public void run(){
	//具体的操作逻辑
	}
}
new MyThread().start();
class MyRunable implements Runnable{
 	@Override
	public void run() {
	}
}
new Thread(new MyRunable()).start();
  • Message.what用来有Hander中用来标注是哪一个子线程发送过来的数据,从而可以对其进行一定规则的处理,就是一个村子里面有很多人一样的,what就是很每个人取一个名字,然后你可以根据名字来区分这些人,然后选择对应的操作。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Change Text"
        android:textAllCaps="false"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:layout_centerInParent="true"/>

</RelativeLayout>
package com.example.androidthreadtest;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.system.StructMsghdr;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    public static final int UPDATE_TEXT = 1;

    private Button button;

    private TextView text;

    private Handler handler = new Handler(Looper.getMainLooper()){
        
        public void handleMessage(Message msg){
            switch (msg.what){
                case UPDATE_TEXT:
                    //这里可以进行UI操作
                    Toast.makeText(MainActivity.this, "主线程", Toast.LENGTH_SHORT).show();
                    text.setText("I Love You 金逸飞");
                    break;
                default:
                    break;
            }
        }

    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = findViewById(R.id.text_view);
        button = findViewById(R.id.button);
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.button:
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        Message message = new Message();
                        message.what = UPDATE_TEXT;
                        handler.sendMessage(message);//将Message对象发送出去
                    }
                }).start();
                break;
            default:
                break;
        }
    }
}

解析异步消息处理机制

名称介绍
Message在线程间传递消息,用于在不同线程间交换数据
Hanlder处理者,主要用于发送和处理消息。一般用sendMessage()发送消息;处理后传递到handlerMessage(),一般需要重写
MessangQueue消息队列,存放通过Hanlder发送的消息,每一个线程只会有一个MessageQueue对象
Looper是MessageQueue的管家,调用loop()后进入无限循环每当发现MessageQueue中存在一条消息,就会将它取出,并传递到Handler的handlerMessage()方法中。每个线程只会有一个Looper对象

步骤

  1. 首先需要在主线程当中创建一个Handler对象,并重写handleMessage()方法。
  2. 然后当子线程中需要进行UI操作时,就创建一个Message对象,并通过Handler将这条消息发送出去(sendMessage()方法)。
  3. 之后这条消息会被添加到MessageQueue的队列中等待被处理,而Looper则会一直尝试从MessageQueue中取出待处理消息
  4. 最后分发回 Handler的handleMessage()方法中。由于Handler是在主线程中创建的,所以此时handleMessage()方法中的代码也会在主线程中运行,于是我们在这里就可以安心地进行UI操作了。
    在这里插入图片描述

另外:runOnUIThread():是一个异步消息处理机制的接口封装。

runOnUiThread(new Runnable() {
        @Override
        public void run() {
        //这里可用于更新UI
        }
});

使用AsyncTask(已弃用)

三个泛型参数:

参数用途
Params在执行AsyncTask时需要传入的参数,可用于在后台任务中使用
Progress后台任务执行时,如果需要在界面上显示当前进度,则使用这里指定的泛型类型作为进度单位
Result当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型类型作为返回值类型

因此,一个最简单的自定义AsyncTask就可以写成如下方式:

class DownloadTask extends AsyncTask<VoidIntegerBoolean> {

重写的方法

方法作用
onPreExecute()在后台任务开始前执行之前的调用,用于进行一些界面上的初始化操作,比如显示一个进度条对话框等等
doInBackground()所有代码在子线程中运行,可以在这里处理所有耗时的任务
onProgressUpdate()这个方法中的参数是在后台任务中传递过来的。在这里可以对UI进行操作。

服务的基本用法

package com.example.servicetestr;

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

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

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

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

    //在启动服务的时候调用
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

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

服务的基本用法

启动和停止服务

MyService.java

package com.example.servicetestr;

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

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

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("MainActivity","onCreate executed");
    }

    //在启动服务的时候调用
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("MainActivity","onStartCommand executed");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("MainActivity","onDestroy executed");
    }
}

MainActivity.java

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button startService = findViewById(R.id.start_service);
        Button stopService = findViewById(R.id.stop_service);
        startService.setOnClickListener(this);
        stopService.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.start_service:{
                Intent startIntent = new Intent(this,MyService.class);
                startService(startIntent);
                break;
            }
            case R.id.stop_service:{
                Intent stopIntent = new Intent(this,MyService.class);
                stopService(stopIntent);
                break;
            }
            default:
                break;
        }
    }

活动和服务进行通信

MainActivity.java

private MyService.DownloadBinder downloadBinder;

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            downloadBinder = (MyService.DownloadBinder) iBinder;
            downloadBinder.startDownload();
            downloadBinder.getProgress();
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button startService = findViewById(R.id.start_service);
        Button stopService = findViewById(R.id.stop_service);
        Button bindService = findViewById(R.id.bind_service);
        Button unbindService = findViewById(R.id.unbind_service);
        startService.setOnClickListener(this);
        stopService.setOnClickListener(this);
        bindService.setOnClickListener(this);
        unbindService.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.start_service:{
                Intent startIntent = new Intent(this,MyService.class);
                startService(startIntent);
                break;
            }
            case R.id.stop_service:{
                Intent stopIntent = new Intent(this,MyService.class);
                stopService(stopIntent);
                break;
            }
            case R.id.bind_service:{
                Intent bindIntent = new Intent(this,MyService.class);
                bindService(bindIntent,connection,BIND_AUTO_CREATE);
                break;
            }
            case R.id.unbind_service:{
                Intent unbindIntent = new Intent(this,MyService.class);
                unbindService(connection);
                break;
            }
            default:
                break;
        }
    }

MyService.java

private DownloadBinder mBinder = new DownloadBinder();

    class DownloadBinder extends Binder{
        public void startDownload(){
            Log.d("MyService","startDownload executed");

        }

        public int getProgress(){
            Log.d("MyService","getProgress executed");
            return 0;
        }
    }

    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

服务的更多技巧

使用前台服务

@Override
        public void onCreate() {
            super.onCreate();
            Log.d("MainActivity","onCreate executed");
            Intent intent = new Intent(this,MainActivity.class);
            PendingIntent pi = PendingIntent.getActivity(this,0, intent,0);
            Notification notification = new NotificationCompat.Builder(this)
                    .setContentTitle("This is content title")
                    .setContentText("This is content text")
                    .setWhen(System.currentTimeMillis())
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
                    .setContentIntent(pi)
                    .build();
            startForeground(1,notification);
    }

IntentService.java

MyIntentService.java

package com.example.servicetestr;

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

import androidx.annotation.Nullable;
import androidx.core.app.JobIntentService;

public class MyIntentService extends IntentService {

    public MyIntentService(String name) {
        super(name);
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        //打印当前线程id
        Log.d("MyIntentService","Thread id is "+Thread.currentThread().getId());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("MyIntentService","onDestroy executed");
    }
}
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-21 15:35:19  更:2021-08-21 15:36:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 9:57:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码