Android组件通信——Service(二十七)

news2024/11/26 4:52:47

1. Service

1.1 知识点

(1)掌握Service与Activity的区别;

(2)掌握Service的定义及使用;

(3)可以使用ServiceConnection 接口绑定一个Service;

(4)了解系统提供的Service程序。

1.2 具体内容

Service是Android四大组件之一,和Activity最大的区别在于一个有界面,一个没有界面。

如果在程序中要实现Services的操作的话,需要定义一个Services类的子类,并且有这个子类复写相应的操作方法。

范例:定义后台服务

       对于后台服务就是指我们Services程序,肯定是没有界面去显示的,就是在后台运行。

<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">
    <Button
        android:id="@+id/start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="启动Services" />
    <Button
        android:id="@+id/stop"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="停止Services" />
</LinearLayout>

关键肯定是要编写我们Services程序。

package com.example.servicesproject;

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

public class MyServices extends Service {
	@Override
	public IBinder onBind(Intent intent) {//绑定Activity
		return null;
	}
	@Override
	public void onCreate() {//创建时调用
		System.out.println("============Service被创建============");
	}
	@Override
	public void onDestroy() {//销毁时调用
		System.out.println("============Service被销毁============");
	}
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {//开始Services
		System.out.println("============Service启动============intent = " + intent + "startId="+startId);
		return Service.START_CONTINUATION_MASK;//表示Service继续执行
	}
}

对于Service,本身并没有界面,只是提供了一个后台的操作,本身需要依靠Activity程序去启动。

package com.example.servicesproject;

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

public class ServicesActivity extends Activity {
	private Button start = null;
	private Button stop = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.activity_services);
		this.start = (Button) super.findViewById(R.id.start);
		this.stop = (Button) super.findViewById(R.id.stop);
		this.start.setOnClickListener(new StartOnClickListenerImpl());
		this.stop.setOnClickListener(new StopOnClickListenerImpl());
	}
	private class StartOnClickListenerImpl implements OnClickListener {
		public void onClick(View v) {
			//启动Service
			ServicesActivity.this.startService(new Intent(ServicesActivity.this,MyServices.class));
		}
	}
	private class StopOnClickListenerImpl implements OnClickListener {
		public void onClick(View v) {
			//停止Service
			ServicesActivity.this.stopService(new Intent(ServicesActivity.this,MyServices.class));
		}
	}
}

通过Activity程序去控制Service的开始和停止,既然Service程序是一个没有界面的Activity,那么肯定也需要在AndroidMainFest.xml里面进行配置。

<service 
            android:name="com.example.servicesproject.MyServices"></service>

如果说一个Activity和Service要进行绑定的话,必须要使用到ServiceConnection这个接口,这个接口中有两个方法,一个是建立连接的时候使用,第二个是取消连接的时候使用, 但是一定要注意,连接是触发的操作中,还有一个IBinder接口对象。

既然IBinder是一个接口,那么这个接口中肯定存在大量的抽象方法,所以按照正常的思路肯定是会去覆写IBinder接口中所有的抽象方法,现在我们可以继承它,我们就可以覆写指定的方法。

package com.example.servicesproject;

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

public class MyServices extends Service {
	private IBinder myIBinder = new Binder(){
		@Override
		public String getInterfaceDescriptor() {//取得接口的描述信息
			return "MyServices.class";
		}
	};
	@Override
	public IBinder onBind(Intent intent) {//绑定Activity
		System.out.println("===========onBind==========intent="+intent);
		return myIBinder;
	}
	
	@Override
	public boolean onUnbind(Intent intent) {//解除绑定
		System.out.println("===========onUnbind==========intent="+intent);
		return super.onUnbind(intent);
	}
	
	@Override
	public void onRebind(Intent intent) {
		System.out.println("===========onRebind==========intent="+intent);
		super.onRebind(intent);
	}

	@Override
	public void onCreate() {//创建时调用
		System.out.println("============Service被创建============");
	}
	@Override
	public void onDestroy() {//销毁时调用
		System.out.println("============Service被销毁============");
	}
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {//开始Services
		System.out.println("============Service启动============intent = " + intent + "startId="+startId);
		return Service.START_CONTINUATION_MASK;//表示Service继续执行
	}
}

而后的Activity程序中增加一些操作按钮。

package com.example.servicesproject;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class ServicesActivity extends Activity {
	private Button start = null;
	private Button stop = null;
	private Button bind = null;
	private Button unbind = null;
	private ServiceConnection serviceConnection = new ServiceConnection(){
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			try {
				System.out.println("==========连接到Service==========" + service.getInterfaceDescriptor());
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
		@Override
		public void onServiceDisconnected(ComponentName name) {
			System.out.println("=================取消Service=============");
		}
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.activity_services);
		this.start = (Button) super.findViewById(R.id.start);
		this.stop = (Button) super.findViewById(R.id.stop);
		this.start.setOnClickListener(new StartOnClickListenerImpl());
		this.stop.setOnClickListener(new StopOnClickListenerImpl());
		this.bind =(Button) super.findViewById(R.id.bind);
		this.unbind = (Button) super.findViewById(R.id.unbind);
		this.bind.setOnClickListener(new BindOnClickListenerImpl());
		this.unbind.setOnClickListener(new UNBindOnClickListenerImpl());
	}
	private class StartOnClickListenerImpl implements OnClickListener {
		public void onClick(View v) {
			//启动Service
			ServicesActivity.this.startService(new Intent(ServicesActivity.this,MyServices.class));
		}
	}
	private class StopOnClickListenerImpl implements OnClickListener {
		public void onClick(View v) {
			//停止Service
			ServicesActivity.this.stopService(new Intent(ServicesActivity.this,MyServices.class));
		}
	}
	private class BindOnClickListenerImpl implements OnClickListener{
		@Override
		public void onClick(View v) {
			//进行Service绑定
			ServicesActivity.this.bindService(new Intent(ServicesActivity.this,MyServices.class), ServicesActivity.this.serviceConnection, Context.BIND_AUTO_CREATE);
		}
	}
	private class UNBindOnClickListenerImpl implements OnClickListener{
		@Override
		public void onClick(View v) {
			//取消绑定
			ServicesActivity.this.unbindService(ServicesActivity.this.serviceConnection);
		}
	}
}

此时的Activity程序就已经完成,下面我们来观察运行消息打印的流程。

·启动Service

01-27 01:07:36.243: INFO/System.out(487): ============Service被创建============
01-27 01:07:36.243: INFO/System.out(487): ============Service启动============intent = Intent { cmp=com.example.servicesproject/.MyServices }startId=1

·绑定Service

01-27 01:08:29.583: INFO/System.out(487): ===========onBind==========intent=Intent { cmp=com.example.servicesproject/.MyServices }
01-27 01:08:29.583: INFO/System.out(487): ==========连接到Service==========MyServices.class

通过打印,可以清楚的发现,出现了onBind之后,会返回到ServiceConnection中执行onServiceConnected()方法。

·如果不启动直接绑定

01-27 01:11:22.652: INFO/System.out(877): ============Service被创建============
01-27 01:11:22.652: INFO/System.out(877): ===========onBind==========intent=Intent { cmp=com.example.servicesproject/.MyServices }
01-27 01:11:22.672: INFO/System.out(877): ==========连接到Service==========MyServices.class

如果直接绑定,则直接调用OnCreate()、onBind()、ServiceConnection中的onServiceConnected()

·不停止,直接退出

01-27 01:12:39.733: I/System.out(877): ===========onUnbind==========intent=Intent { cmp=com.example.servicesproject/.MyServices }
01-27 01:12:39.733: I/System.out(877): ============Service被销毁============

不停止直接退出,会先取消绑定,再销毁。

·返回到Activity,同时再设置绑定

01-27 01:13:50.274: INFO/System.out(877): ============Service被创建============
01-27 01:13:50.274: INFO/System.out(877): ===========onBind==========intent=Intent { cmp=com.example.servicesproject/.MyServices }
01-27 01:13:50.292: INFO/System.out(877): ==========连接到Service==========MyServices.class

·解除绑定

01-27 01:14:19.702: INFO/System.out(877): ===========onUnbind==========intent=Intent { cmp=com.example.servicesproject/.MyServices }
01-27 01:14:19.702: INFO/System.out(877): ============Service被销毁============

也就是说,我们在操作之中,主应该注意的方法是:OnCreate()、onBind()、onUnbind(),onDestroy()。

虽然,以上的程序已经进行了绑定,但是还存在一个问题 。

定义一个空的接口,作为一个标识。

public interface IService {
}

此接口中不需要编写任何的操作方法。

package com.example.servicesproject;

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

public class MyServices extends Service {
	private IBinder myIBinder = new IBinderImpl();
	private class IBinderImpl extends Binder implements IService{

		@Override
		public String getInterfaceDescriptor() {//取得接口信息
			return "MyServices.class";
		}
		
	}
	@Override
	public IBinder onBind(Intent intent) {//绑定Activity
		System.out.println("===========onBind==========intent="+intent);
		return myIBinder;
	}
	
	@Override
	public boolean onUnbind(Intent intent) {//解除绑定
		System.out.println("===========onUnbind==========intent="+intent);
		return super.onUnbind(intent);
	}
	
	@Override
	public void onRebind(Intent intent) {
		System.out.println("===========onRebind==========intent="+intent);
		super.onRebind(intent);
	}

	@Override
	public void onCreate() {//创建时调用
		System.out.println("============Service被创建============");
	}
	@Override
	public void onDestroy() {//销毁时调用
		System.out.println("============Service被销毁============");
	}
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {//开始Services
		System.out.println("============Service启动============intent = " + intent + "startId="+startId);
		return Service.START_CONTINUATION_MASK;//表示Service继续执行
	}
}

大家一定要记住,IBinderImpl一定要是Binder和IService共同子类。

package com.example.servicesproject;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class ServicesActivity extends Activity {
	private Button start = null;
	private Button stop = null;
	private Button bind = null;
	private Button unbind = null;
	private IService service = null;
	private ServiceConnection serviceConnection = new ServiceConnectionImpl();
	private class ServiceConnectionImpl implements ServiceConnection{
			@Override
			public void onServiceConnected(ComponentName name, IBinder service) {
				try {
					System.out.println("==========连接到Service==========" + service.getInterfaceDescriptor());
				} catch (RemoteException e) {
					e.printStackTrace();
				}
			}
			@Override
			public void onServiceDisconnected(ComponentName name) {
				System.out.println("=================取消Service=============");
			}
	}
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.activity_services);
		this.start = (Button) super.findViewById(R.id.start);
		this.stop = (Button) super.findViewById(R.id.stop);
		this.start.setOnClickListener(new StartOnClickListenerImpl());
		this.stop.setOnClickListener(new StopOnClickListenerImpl());
		this.bind =(Button) super.findViewById(R.id.bind);
		this.unbind = (Button) super.findViewById(R.id.unbind);
		this.bind.setOnClickListener(new BindOnClickListenerImpl());
		this.unbind.setOnClickListener(new UNBindOnClickListenerImpl());
	}
	private class StartOnClickListenerImpl implements OnClickListener {
		public void onClick(View v) {
			//启动Service
			ServicesActivity.this.startService(new Intent(ServicesActivity.this,MyServices.class));
		}
	}
	private class StopOnClickListenerImpl implements OnClickListener {
		public void onClick(View v) {
			//停止Service
			ServicesActivity.this.stopService(new Intent(ServicesActivity.this,MyServices.class));
		}
	}
	private class BindOnClickListenerImpl implements OnClickListener{
		@Override
		public void onClick(View v) {
			//进行Service绑定
			ServicesActivity.this.bindService(new Intent(ServicesActivity.this,MyServices.class), ServicesActivity.this.serviceConnection, Context.BIND_AUTO_CREATE);
		}
	}
	private class UNBindOnClickListenerImpl implements OnClickListener{
		@Override
		public void onClick(View v) {
			if(null != ServicesActivity.this.service){
				//取消绑定
				ServicesActivity.this.unbindService(ServicesActivity.this.serviceConnection);
				ServicesActivity.this.service = null;
			}
			
		}
	}
}

关键就是IBinder需要继承Binder还需要实现我们定义的空的接口。

·操作系统服务:服务的概念就是运行在后台之中,而且android之中为了方便的系统运行,也有多种服务提供给开发者使用。

范例:剪贴板服务

<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">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

如果需要取得系统服务,需要使用getSystemService(服务标记);

package com.example.contextservice;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.ClipboardManager;

public class ContextServiceActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.activity_context_service);
		ClipboardManager clipboardManager = (ClipboardManager)super.getSystemService(Context.CLIPBOARD_SERVICE);//取得剪贴板服务
		clipboardManager.setText("毛栗子");
	}
}

这边就是直接使用了后台提供的服务。

范例:取得正在运行的Activity程序信息

<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" >
    <ListView
        android:id="@+id/aclist"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</LinearLayout>

肯定是需要通过Activity程序取得所有信息并在ListView中显示。

package com.example.activityrun;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {
	private ListView aclist = null;
	private ListAdapter adapter = null;
	private List<String> all = new ArrayList<String>();
	private List<ActivityManager.RunningTaskInfo> allTaskInfo = null;//所有任务信息
	private ActivityManager activityManager = null;//ActivityManager对象
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.activity_main);
		this.aclist = (ListView) super.findViewById(R.id.aclist);
		this.activityManager = (ActivityManager)super.getSystemService(Context.ACTIVITY_SERVICE);
		this.listActivity();
	}
	public void listActivity(){
		this.allTaskInfo = this.activityManager.getRunningTasks(30);//取回30笔任务数据
		Iterator<ActivityManager.RunningTaskInfo> it = this.allTaskInfo.iterator();
		while(it.hasNext()){
			ActivityManager.RunningTaskInfo task = it.next();
			this.all.add("【ID】"+task.id+"【NAME】"+task.baseActivity.getClassName());
		}
		this.adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,this.all);
		this.aclist.setAdapter(this.adapter);
	}
}

需要配置权限:

<uses-permission android:name="android.permission.GET_TASKS"/>

如果说要取得服务信息,则直接修改以上的程序就可以了。如果是要取得所有的进程信息,我们也只需要修改以上的程序。

范例:取得网络信息

如果要获取手机讯息,我们肯定也需要使用列表完成显示。

package com.example.activityrun;

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

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;

public class MainActivity extends Activity {
	private ListView telinfo = null;
	private ListAdapter adapter = null;
	private List<String> all = new ArrayList<String>();
	private TelephonyManager telephonyManager = null;//ActivityManager对象
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.activity_main);
		this.telinfo = (ListView) super.findViewById(R.id.aclist);
		this.telephonyManager = (TelephonyManager)super.getSystemService(Context.TELEPHONY_SERVICE);
		this.listActivity();
	}
	public void listActivity(){
		this.all.add(this.telephonyManager.getLine1Number()==null?"没有手机号码":"手机号:"+this.telephonyManager.getLine1Number());
		this.all.add(this.telephonyManager.getNetworkOperatorName()== null?"没有移动服务商":"移动服务商:"+this.telephonyManager.getNetworkOperatorName());
		if(this.telephonyManager.getPhoneType() == TelephonyManager.NETWORK_TYPE_CDMA){
			this.all.add("移动网络:CDMA");
		}else if(this.telephonyManager.getPhoneType() == TelephonyManager.NETWORK_TYPE_GPRS){
			this.all.add("移动网络:GPRS");
		}else{
			this.all.add("移动网络:未知");
		}
		this.all.add("是否漫游:"+(this.telephonyManager.isNetworkRoaming()?"是漫游":"非漫游"));
		this.adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,this.all);
		this.telinfo.setAdapter(this.adapter);
	}
}

权限:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

范例:操作WIFI

<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" >
    <TextView
        android:id="@+id/mag"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <Button
        android:id="@+id/openWIFI"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="打开WIFI"/>
    <Button
        android:id="@+id/closeWIFI"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="关闭WIFI"/>
    <Button
        android:id="@+id/selectState"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="检查WIFI状态"/>
</LinearLayout>

package com.example.activityrun;

import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {
	private TextView msg = null;
	private Button openWIFI = null;
	private Button closeWIFI = null;
	private Button selectState = null;
	private WifiManager wifiManager = null;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setContentView(R.layout.activity_main);
		this.msg = (TextView) super.findViewById(R.id.mag);
		this.openWIFI = (Button) super.findViewById(R.id.openWIFI);
		this.closeWIFI = (Button) super.findViewById(R.id.closeWIFI);
		this.selectState = (Button) super.findViewById(R.id.selectState);
		this.wifiManager = (WifiManager)super.getSystemService(Context.WIFI_SERVICE);
		this.openWIFI.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				MainActivity.this.wifiManager.setWifiEnabled(true);//启动WIFI
				MainActivity.this.msg.setText("打开WIFI,状态:" + MainActivity.this.wifiManager.getWifiState());
			}
		});
		this.closeWIFI.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				MainActivity.this.wifiManager.setWifiEnabled(false);//关闭WIFI
				MainActivity.this.msg.setText("关闭WIFI,状态:" + MainActivity.this.wifiManager.getWifiState());
			}
		});
		this.selectState.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				MainActivity.this.msg.setText("检查WIFI,状态:" + MainActivity.this.wifiManager.getWifiState());
			}
		});
	}
}

配置权限:

<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
	<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
	<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

1.3 小结

(1)Service是在后台运行的一种无界面的Activity程序;

(2)在Android系统之中提供了多种Service供用户使用;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1092951.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java js 经纬度转换 大地坐标(高斯投影坐标)与经纬度互相转换

项目中有大地坐标(高斯投影坐标)与经纬度互相转换的需求 写了个工具类; 有java和js代码 如图 java代码中将坐标系和带宽已作为参数传入方法,使用时只需调用不同方法: js端没有将坐标系和带宽作为参数 如果有需要可以替换注释地方 或者自行修改为传参方式: 接下来贴代码: jav…

C++笔记之如何给 `const char*` 类型变量赋值

C笔记之如何给 const char* 类型变量赋值 code review! 文章目录 C笔记之如何给 const char* 类型变量赋值1.在C中&#xff0c;如果你要给一个 const char* 变量赋值&#xff0c;你通常有几种方法来做这件事&#xff0c;具体取决于你的需求。下面是一些常见的方法&#xff1a;…

使用JAVA发送邮件

这里用java代码编写发送邮件我采用jar包&#xff0c;需要先点击这里下载三个jar包&#xff1a;这三个包分别为&#xff1a;additionnal.jar&#xff1b;activation.jar&#xff1b;mail.jar。这三个包缺一不可&#xff0c;如果少添加或未添加均会报下面这个错误&#xff1a; C…

芯片学习记录SN74HC14DR

SN74HC14DR 芯片介绍 该设备包含六个独立的逆变器使用施密特触发器输入。每个门执行正逻辑中的布尔函数Y/A("/"表示“非”)。 引脚信息 引脚名称I/O电平功能11AI0~vcc输入21YO0~vcc输出7GND-电源14VCC-3.3v电源&#xff08;2~6V&#xff09;Y/A 推荐使用条件 参数…

jwt的使用概念工具类与切入spa项目

jwt的概念 JWT&#xff08;JSON Web Token&#xff09;是一种用于身份验证和授权的开放标准&#xff0c;它是一种轻量级的、安全的、基于JSON的令牌机制。 JWT由三部分组成&#xff1a;头部&#xff08;Header&#xff09;、载荷&#xff08;Payload&#xff09;和签名&#…

C++笔记之std::async的用法

C笔记之std::async的用法 code review! 文章目录 C笔记之std::async的用法1.概念2.C 异步任务的使用示例 - 使用 std::async 和 std::future3. std::launch::async 和 std::launch::deferred 1.概念 std::async 是 C 标准库中的一个函数&#xff0c;用于创建异步任务&#xf…

leetCode 1035.不相交的线 动态规划 + 滚动数组 (最长公共子序列)

1035. 不相交的线 - 力扣&#xff08;LeetCode&#xff09; 在两条独立的水平线上按给定的顺序写下 nums1 和 nums2 中的整数。 现在&#xff0c;可以绘制一些连接两个数字 nums1[i] 和 nums2[j] 的直线&#xff0c;这些直线需要同时满足满足&#xff1a; nums1[i] nums2[j]…

3.4 构造方法

思维导图&#xff1a; 3.4.1 定义构造方法 ### Java中的构造方法 #### **定义与目的** 构造方法&#xff0c;也称为构造器&#xff0c;是一个特殊的成员方法&#xff0c;用于在实例化对象时为对象赋值或执行初始化操作。其主要目的是确保对象在被创建时具有有效和合适的初始状…

学习记忆——数学篇——代数——记忆宫殿——卧室

明确需放置的大件物品 整式、分式 &#xff08;1&#xff09;整式&#xff1a;运算、因式定理 &#xff08;2&#xff09;分式&#xff1a;运算函数、方程与不等式 &#xff08;1&#xff09;函数&#xff1a;一元二次函数、 &#xff08;2&#xff09;方程&#xff1a;一元二…

Mysql高级——事务(2)

MySQL事务日志 事务有4种特性&#xff1a;原子性、一致性、隔离性和持久性。那么事务的四种特性到底是基于什么机制实现呢&#xff1f; 事务的隔离性由锁机制实现。 而事务的原子性、一致性和持久性由事务的 redo 日志和undo 日志来保证。 REDO LOG 称为重做日志&#xff0c;…

默认关闭idea2020的注释doc的rendered view模式(阅读模式)

idea2020的javadoc有了一个rendered模式,在开发的时候感觉很不习惯… 打开sessings,在编辑器的外观中取消这个选项,默认情况下doc就是编辑模式了,点击左侧的图标就会变为rendered view模式

输入法显示到语言栏_状态栏

设置–时间和语言–语言–最右侧"相关设置"中的"拼写、键入和键盘设置" 最下方的"高级键盘设置"–“使用桌面语言栏(如果可用)” 点击"语言栏选项" 接下来就是不同输入法的设置了 搜狗输入法:右键输入法选择"隐藏状态栏"–…

全新整合热搜榜单热门榜单内容系统聚合源码/带教程安装

源码简介&#xff1a; 在移动互联网时代&#xff0c;我们每天都会接收到大量的信息&#xff0c;但是想要知道哪些是最热门的话题和内容&#xff0c;往往需要花费很多精力去搜索和筛选。因为有这个需要&#xff0c;一个全新整合热搜榜单热门榜单内容系统聚合源码就应运而生了&a…

Zabbix监控系统详解2:基于Proxy分布式实现Web应用监控及Zabbix 高可用集群的搭建

文章目录 1. zabbix-proxy的分布式监控的概述1.1 分布式监控的主要作用1.2 监控数据流向1.3 构成组件1.3.1 zabbix-server1.3.2 Database1.3.3 zabbix-proxy1.3.4 zabbix-agent1.3.5 web 界面 2. 部署zabbix代理服务器2.1 前置准备2.2 配置 zabbix 的下载源&#xff0c;安装 za…

1.1 Windows驱动开发:配置驱动开发环境

在进行驱动开发之前&#xff0c;您需要先安装适当的开发环境和工具。首先&#xff0c;您需要安装Windows驱动开发工具包&#xff08;WDK&#xff09;&#xff0c;这是一组驱动开发所需的工具、库、示例和文档。然后&#xff0c;您需要安装Visual Studio开发环境&#xff0c;以便…

回归预测 | MATLAB实现BO-LSSVM贝叶斯优化算法优化最小二乘支持向量机数据回归预测(多指标,多图)

回归预测 | MATLAB实现BO-LSSVM贝叶斯优化算法优化最小二乘支持向量机数据回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现BO-LSSVM贝叶斯优化算法优化最小二乘支持向量机数据回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果…

Stream流中的常用方法(forEach,filter,map,count,limit,skip,concat)和Stream流的特点

1、forEach方法 该方法接收一个Consumer接口是一个 消费型 的函数式接口&#xff0c;可以传递Lambda表达式&#xff0c;消费数据用来遍历流中的数据&#xff0c;是一个 终结 方法&#xff0c;遍历 之后就不能继续调用Stream流中的其他方法 package com.csdn.stream; import jav…

【数字IC设计】DC自动添加门控时钟

简介 数字电路的动态功耗主要是由于寄存器翻转带来的&#xff0c;为了降低芯片内部功耗&#xff0c;门控时钟的方案应运而生。作为低功耗设计的一种方法&#xff0c;门控时钟是指在数据无效时将寄存器的时钟关闭&#xff0c;以此来降低动态功耗。 在下图中&#xff0c;展示了…

【Matlab】二维绘图函数汇总

目录 1. plot() 2. subplot() 3. fplot() 4. polarplot() 1. plot() plot() 函数是 Matlab 中最常用的绘图函数&#xff0c;用于在平面直角坐标系中绘制直线或曲线。 用法&#xff1a; plot(X,Y) plot(X,Y,LineSpec) plot(X1,Y1, ... ,Xn,Yn) 说明&#xff1a; plot(X,Y) …

【软考-中级】系统集成项目管理工程师-立项管理历年案例

持续更新。。。。。。。。。。。。。。。 目录 2023 上 试题一(18分) 2023 上 试题一(18分) A公司跨国收购了B公司的主营业务&#xff0c;保留了B公司原有的人员组织结构和内部办公系统。 为了解决B公司内部办公系统与A公司原有系统不兼容的问题&#xff0c;财务、人力和行政部…