Android在framework层添加自定义服务的流程

环境说明

  • ubuntu16.04
  • android4.1
  • java version “1.6.0_45”
  • GNU Make 3.81
  • gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12)

可能有人会问,现在都2024了怎么还在用android4版本,早都过时了。确实,现在最新的都是Android13、Android14了,不过我这里主要是用于demo的演示学习使用,只要整个的流程掌握了,哪个版本的流程都是大同小异;再一个就拿Android13来说,源码100G多非常庞大,代码clone、源码编译都是很慢的,而Android4.1源码才4G多,编译运行就快多了,省时省力。

编写AIDL文件

如果不了解aidl,建议先看看:android AIDL使用demo
仿照系统中现有服务的编写方式,新增服务需要编写aidl接口(也就是提供什么服务),在frameworks/base/core/java/android/helloservice/新建aidl文件,
在这里插入图片描述
ICallBack.aidl内容如下

package android.helloservice;
interface ICallBack {
    void onReceive(String serverMsg);
}

IHelloService.aidl内容如下

package android.helloservice;
import android.helloservice.ICallBack;
interface IHelloService {
     String getHello(String send);
     void registerCallback(ICallBack callback);
     void unRegisterCallback(ICallBack callback);
}

修改frameworks/base/Android.mk,在LOCAL_SRC_FILES变量中加入新增的aidl文件

## READ ME: ########################################################
##
## When updating this list of aidl files, consider if that aidl is
## part of the SDK API.  If it is, also add it to the list below that
## is preprocessed and distributed with the SDK.  This list should
## not contain any aidl files for parcelables, but the one below should
## if you intend for 3rd parties to be able to send those objects
## across process boundaries.
##
## READ ME: ########################################################
LOCAL_SRC_FILES += \
	core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl \
	core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl \
	core/java/com/android/internal/widget/IRemoteViewsFactory.aidl \
	core/java/com/android/internal/widget/IRemoteViewsAdapterConnection.aidl \
	//省略部分
	core/java/android/helloservice/ICallBack.aidl \
	core/java/android/helloservice/IHelloService.aidl \

执行mmm frameworks/base单编,编译成功之后会在out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/helloservice/生成如下文件在这里插入图片描述
IHelloService.java内容(androidstudio生成,aosp生成的代码紧凑不方便阅读)

/*
 * This file is auto-generated.  DO NOT MODIFY.
 */
package android.helloservice;
public interface IHelloService extends android.os.IInterface
{
  /** Default implementation for IHelloService. */
  public static class Default implements android.helloservice.IHelloService
  {
    @Override public java.lang.String getHello(java.lang.String send) throws android.os.RemoteException
    {
      return null;
    }
    @Override public void registerCallback(android.helloservice.ICallBack callback) throws android.os.RemoteException
    {
    }
    @Override public void unRegisterCallback(android.helloservice.ICallBack callback) throws android.os.RemoteException
    {
    }
    @Override
    public android.os.IBinder asBinder() {
      return null;
    }
  }
  /** Local-side IPC implementation stub class. */
  public static abstract class Stub extends android.os.Binder implements android.helloservice.IHelloService
  {
    /** Construct the stub at attach it to the interface. */
    public Stub()
    {
      this.attachInterface(this, DESCRIPTOR);
    }
    /**
     * Cast an IBinder object into an android.helloservice.IHelloService interface,
     * generating a proxy if needed.
     */
    public static android.helloservice.IHelloService asInterface(android.os.IBinder obj)
    {
      if ((obj==null)) {
        return null;
      }
      android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
      if (((iin!=null)&&(iin instanceof android.helloservice.IHelloService))) {
        return ((android.helloservice.IHelloService)iin);
      }
      return new android.helloservice.IHelloService.Stub.Proxy(obj);
    }
    @Override public android.os.IBinder asBinder()
    {
      return this;
    }
    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
    {
      java.lang.String descriptor = DESCRIPTOR;
      if (code >= android.os.IBinder.FIRST_CALL_TRANSACTION && code <= android.os.IBinder.LAST_CALL_TRANSACTION) {
        data.enforceInterface(descriptor);
      }
      switch (code)
      {
        case INTERFACE_TRANSACTION:
        {
          reply.writeString(descriptor);
          return true;
        }
      }
      switch (code)
      {
        case TRANSACTION_getHello:
        {
          java.lang.String _arg0;
          _arg0 = data.readString();
          java.lang.String _result = this.getHello(_arg0);
          reply.writeNoException();
          reply.writeString(_result);
          break;
        }
        case TRANSACTION_registerCallback:
        {
          android.helloservice.ICallBack _arg0;
          _arg0 = android.helloservice.ICallBack.Stub.asInterface(data.readStrongBinder());
          this.registerCallback(_arg0);
          reply.writeNoException();
          break;
        }
        case TRANSACTION_unRegisterCallback:
        {
          android.helloservice.ICallBack _arg0;
          _arg0 = android.helloservice.ICallBack.Stub.asInterface(data.readStrongBinder());
          this.unRegisterCallback(_arg0);
          reply.writeNoException();
          break;
        }
        default:
        {
          return super.onTransact(code, data, reply, flags);
        }
      }
      return true;
    }
    private static class Proxy implements android.helloservice.IHelloService
    {
      private android.os.IBinder mRemote;
      Proxy(android.os.IBinder remote)
      {
        mRemote = remote;
      }
      @Override public android.os.IBinder asBinder()
      {
        return mRemote;
      }
      public java.lang.String getInterfaceDescriptor()
      {
        return DESCRIPTOR;
      }
      @Override public java.lang.String getHello(java.lang.String send) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        java.lang.String _result;
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeString(send);
          boolean _status = mRemote.transact(Stub.TRANSACTION_getHello, _data, _reply, 0);
          _reply.readException();
          _result = _reply.readString();
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
        return _result;
      }
      @Override public void registerCallback(android.helloservice.ICallBack callback) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeStrongInterface(callback);
          boolean _status = mRemote.transact(Stub.TRANSACTION_registerCallback, _data, _reply, 0);
          _reply.readException();
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
      }
      @Override public void unRegisterCallback(android.helloservice.ICallBack callback) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeStrongInterface(callback);
          boolean _status = mRemote.transact(Stub.TRANSACTION_unRegisterCallback, _data, _reply, 0);
          _reply.readException();
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
      }
    }
    static final int TRANSACTION_getHello = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    static final int TRANSACTION_registerCallback = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
    static final int TRANSACTION_unRegisterCallback = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
  }
  public static final java.lang.String DESCRIPTOR = "android.helloservice.IHelloService";
  public java.lang.String getHello(java.lang.String send) throws android.os.RemoteException;
  public void registerCallback(android.helloservice.ICallBack callback) throws android.os.RemoteException;
  public void unRegisterCallback(android.helloservice.ICallBack callback) throws android.os.RemoteException;
}

ICallBack.java内容(androidstudio生成)

/*
 * This file is auto-generated.  DO NOT MODIFY.
 */
package android.helloservice;
public interface ICallBack extends android.os.IInterface
{
  /** Default implementation for ICallBack. */
  public static class Default implements android.helloservice.ICallBack
  {
    @Override public void onReceive(java.lang.String serverMsg) throws android.os.RemoteException
    {
    }
    @Override
    public android.os.IBinder asBinder() {
      return null;
    }
  }
  /** Local-side IPC implementation stub class. */
  public static abstract class Stub extends android.os.Binder implements android.helloservice.ICallBack
  {
    /** Construct the stub at attach it to the interface. */
    public Stub()
    {
      this.attachInterface(this, DESCRIPTOR);
    }
    /**
     * Cast an IBinder object into an android.helloservice.ICallBack interface,
     * generating a proxy if needed.
     */
    public static android.helloservice.ICallBack asInterface(android.os.IBinder obj)
    {
      if ((obj==null)) {
        return null;
      }
      android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
      if (((iin!=null)&&(iin instanceof android.helloservice.ICallBack))) {
        return ((android.helloservice.ICallBack)iin);
      }
      return new android.helloservice.ICallBack.Stub.Proxy(obj);
    }
    @Override public android.os.IBinder asBinder()
    {
      return this;
    }
    @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
    {
      java.lang.String descriptor = DESCRIPTOR;
      if (code >= android.os.IBinder.FIRST_CALL_TRANSACTION && code <= android.os.IBinder.LAST_CALL_TRANSACTION) {
        data.enforceInterface(descriptor);
      }
      switch (code)
      {
        case INTERFACE_TRANSACTION:
        {
          reply.writeString(descriptor);
          return true;
        }
      }
      switch (code)
      {
        case TRANSACTION_onReceive:
        {
          java.lang.String _arg0;
          _arg0 = data.readString();
          this.onReceive(_arg0);
          reply.writeNoException();
          break;
        }
        default:
        {
          return super.onTransact(code, data, reply, flags);
        }
      }
      return true;
    }
    private static class Proxy implements android.helloservice.ICallBack
    {
      private android.os.IBinder mRemote;
      Proxy(android.os.IBinder remote)
      {
        mRemote = remote;
      }
      @Override public android.os.IBinder asBinder()
      {
        return mRemote;
      }
      public java.lang.String getInterfaceDescriptor()
      {
        return DESCRIPTOR;
      }
      @Override public void onReceive(java.lang.String serverMsg) throws android.os.RemoteException
      {
        android.os.Parcel _data = android.os.Parcel.obtain();
        android.os.Parcel _reply = android.os.Parcel.obtain();
        try {
          _data.writeInterfaceToken(DESCRIPTOR);
          _data.writeString(serverMsg);
          boolean _status = mRemote.transact(Stub.TRANSACTION_onReceive, _data, _reply, 0);
          _reply.readException();
        }
        finally {
          _reply.recycle();
          _data.recycle();
        }
      }
    }
    static final int TRANSACTION_onReceive = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
  }
  public static final java.lang.String DESCRIPTOR = "android.helloservice.ICallBack";
  public void onReceive(java.lang.String serverMsg) throws android.os.RemoteException;
}

编写系统服务

上面aidl是定义服务接口,下面开始编写一个系统服务来实现接口。参考系统服务MountService.java的路径编写frameworks/base/services/java/com/android/server/HelloService.java

package com.android.server;

import android.content.Context;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;
import android.helloservice.ICallBack;
import android.helloservice.IHelloService;
public class HelloService extends IHelloService.Stub {
    private static final String TAG = "HelloService";
    private RemoteCallbackList<ICallBack> callbackList = new RemoteCallbackList();
    private Context context;

    public HelloService(Context context) {
        this.context = context;
        Log.d(TAG, "HelloService() init");
    }

    @Override
    public String getHello(String send) throws RemoteException {
        Log.d(TAG, "getHello() called with: send = [" + send + "]");
        int num = callbackList.beginBroadcast();
        for (int i = 0; i < num; i++) {
            ICallBack callback = callbackList.getBroadcastItem(i);
            if (callback != null) {
                callback.onReceive("callback from HelloService with:" + send);
            }
        }
        callbackList.finishBroadcast();
        return send + ",server receive ok";
    }

    @Override
    public void registerCallback(ICallBack callback) throws RemoteException {
        callbackList.register(callback);
        Log.d(TAG, "registerCallback() called with: callback = [" + callback + "]");
    }

    @Override
    public void unRegisterCallback(ICallBack callback) throws RemoteException {
        callbackList.unregister(callback);
        Log.d(TAG, "unRegisterCallback() called with: callback = [" + callback + "]");
    }
}

注册系统服务

所有系统服务都运行在名为 system_server 的进程中,我们也要把服务加入进去。系统中已有很多服务了,我们把它加入到最后,修改frameworks/base/services/java/com/android/server/SystemServer.java

 	@Override
    public void run() {
    ...省略部分
    	try {
            Slog.i(TAG, "Entropy Mixer");
            ServiceManager.addService("entropy", new EntropyMixer());
			
			//HelloService的name必须唯一
		    Slog.i(TAG, "HelloService");
            ServiceManager.addService("HelloService", new HelloService(context));
        }
    }

执行mmm frameworks/base/services/java/编译service模块
执行make snod重新打包system.img
执行emulator重启模拟器,发现一直停留在重启界面。在这里插入图片描述
无奈,执行make -j30(本机16核32线程)重编也报错,提示如下

PRODUCT_COPY_FILES device/generic/goldfish/data/etc/apns-conf.xml:system/etc/apns-conf.xml ignored.
Checking API: checkapi-current
target Java: services (out/target/common/obj/JAVA_LIBRARIES/services_intermediates/classes)
out/target/common/obj/PACKAGING/public_api.txt:10084: error 2: Added package android.helloservice

******************************
You have tried to change the API from what has been previously approved.

To make these errors go away, you have two choices:
   1) You can add "@hide" javadoc comments to the methods, etc. listed in the
      errors above.

   2) You can update current.txt by executing the following command:
         make update-api

      To submit the revised current.txt to the main Android repository,
      you will need approval.
******************************

根据错误提示执行下面命令

make update-api
make -j30
emulator

模拟器重启成功,且看到HelloService相关日志,说明HelloService服务添加成功。

I/InputManager(  147): Starting input manager
D/PermissionCache(   35): checking android.permission.ACCESS_SURFACE_FLINGER for uid=1000 => granted (1193 us)
I/WindowManager(  147): Enabled StrictMode logging for WMThread's Looper
I/SystemServer(  147): HelloService
D/HelloService(  147): HelloService() init
I/SystemServer(  147): No Bluetooh Service (emulator)

App调用服务

framework层添加服务成功后,app如何使用服务呢?有两种方式,下面一一讲解

方式1:拿到AIDL文件直接访问

为了方便开发,用androidstudio新建一个项目名字就叫Hello。把上面的两个aidl文件复制到项目,保持aidl的包名结构,在这里插入图片描述

MainActivity内容如下,其中ServiceManager会报红不用管,因为等下我们要拷贝项目到aosp源码环境下编译,源码环境下可以正常编过。

package com.hai.hello;

import android.app.Activity;
import android.helloservice.ICallBack;
import android.helloservice.IHelloService;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import android.view.View;

public class MainActivity extends Activity {
    private static final String TAG = "MainActivity";
    IHelloService mService;
    ICallBack.Stub callback = new ICallBack.Stub() {
        @Override
        public void onReceive(String serverMsg) throws RemoteException {
            Log.d(TAG, "onReceive() called with: serverMsg = [" + serverMsg + "]");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mService = IHelloService.Stub.asInterface(ServiceManager.getService("HelloService"));
        Log.d(TAG, "onCreate: " + mService);
        try {
            mService.registerCallback(callback);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
        try {
            mService.getHello("client say hello");
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }

        try {
            mService.unRegisterCallback(callback);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }
}

把项目拷贝到packages/experimental/目录下。参考此目录下的其他app的项目结构,移除不要的文件,最终Hello的目录结构如图在这里插入图片描述
Android.mk内容如下

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
#LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_SRC_FILES += aidl/android/helloservice/IHelloService.aidl
LOCAL_SRC_FILES += aidl/android/helloservice/ICallBack.aidl
LOCAL_PACKAGE_NAME := Hello
LOCAL_CERTIFICATE := platform
include $(BUILD_PACKAGE)

执行以下命令单编Hello项目,重启模拟器,

mmm packages/experimental/Hello
make snod
emulator

在这里插入图片描述
点击启动app,从日志可以看到Hello app启动成功并和HelloService正确交互了。

方式2:通过getSystemService访问

为了方便开发者使用,我们也提供通用接口context.getSystemService()方式获取服务。仿照AccountManager我们也写一个类就叫HelloManager吧,
frameworks/base/core/java/android/helloservice/HelloManager.java内容如下

package android.helloservice;
import android.content.Context;
import android.helloservice.ICallBack;
import android.helloservice.IHelloService;
import android.os.RemoteException;
import android.util.Log;

public class HelloManager {
    private static final String TAG = "HelloManager";
    private Context context;
    private IHelloService service;

    public HelloManager(Context context, IHelloService service) {
        this.context = context;
        this.service = service;
        Log.d(TAG, "HelloManager()");
    }

    public String getHello(String send) {
        try {
            return service.getHello(send);
        } catch (RemoteException ex) {
            throw new RuntimeException(ex);
        }
    }

    public void registerCallback(ICallBack callback) {
        try {
            service.registerCallback(callback);
        } catch (RemoteException ex) {
            throw new RuntimeException(ex);
        }
    }

    public void unRegisterCallback(ICallBack callback) {
        try {
            service.unRegisterCallback(callback);
        } catch (RemoteException ex) {
            throw new RuntimeException(ex);
        }
    }
}

HelloManager写好之后需要注册到context中,修改frameworks/base/core/java/android/app/ContextImpl.java如下:

import android.helloservice.IHelloService;
import android.helloservice.HelloManager; 
static {
		...省略部分   
        registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
                public Object getService(ContextImpl ctx) {
                    return AccessibilityManager.getInstance(ctx);
                }});
             
	    registerService("HelloService", new ServiceFetcher() {
                public Object createService(ContextImpl ctx) {
                    IBinder b = ServiceManager.getService("HelloService");
                    IHelloService service = IHelloService.Stub.asInterface(b);
                    return new HelloManager(ctx, service);
                }});

        registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
                public Object createService(ContextImpl ctx) {
                    return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
                }});

然后是app使用,这里还是使用Hello项目,修改MainActivity内容如下

package com.hai.hello;
import android.app.Activity;
import android.helloservice.ICallBack;
import android.helloservice.IHelloService;
import android.helloservice.HelloManager;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import android.view.View;

public class MainActivity extends Activity {
    private static final String TAG = "MainActivity";
    IHelloService mService;
    ICallBack.Stub callback = new ICallBack.Stub() {
        @Override
        public void onReceive(String serverMsg) throws RemoteException {
            Log.d(TAG, "onReceive() called with: serverMsg = [" + serverMsg + "]");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
	    HelloManager helloManager=(HelloManager) getSystemService("HelloService");
        Log.d(TAG, "HelloManager onCreate: " + mService);
        helloManager.registerCallback(callback);
        helloManager.getHello("client say hello");
        helloManager.unRegisterCallback(callback);
    }
}

执行下面命令

mmm packages/experimental/Hello/
make update-api
make -j30
emulator

模拟器重启后看到如下日志,说明getSystemService的方式也访问成功。
在这里插入图片描述
参考:
Android 添加系统服务的完整流程SystemService
为Android系统的Application Frameworks层增加硬件访问服务
为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在Linux环境下搭建Redis服务结合内网穿透实现通过GUI工具远程管理数据库

文章目录 前言1. 安装Docker步骤2. 使用docker拉取redis镜像3. 启动redis容器4. 本地连接测试4.1 安装redis图形化界面工具4.2 使用RDM连接测试 5. 公网远程访问本地redis5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定TCP地址远程访问 前言 本文主要介绍如何在Li…

Python处理表格数据常用的 N+个操作

Python作为一种强大且易用的编程语言&#xff0c;其在数据处理方面表现尤为出色。特别是当我们面对大量的表格数据时&#xff0c;Python的各类库和工具可以极大地提高我们的工作效率。以下&#xff0c;我将详细介绍Python处理表格数据常用的操作。 首先&#xff0c;我们需要安…

【算法笔记自学】第 3 章 入门篇(1)——入门模拟

3.1简单模拟 自己写的题解 #include <stdio.h> #include <stdlib.h> int main() {int N;int num0;scanf("%d",&N);while(N!1){if(N%20){NN/2;}else{N(3*N1)/2;}num;}printf("%d",num);system("pause"); // 防止运行后自动退出&…

SpringBoot+OSS实现文件上传

创建spring boot项目 pom依赖 <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.17.4</version></dependency><dependency><groupId>javax.xml.bind</groupI…

Transformer前置知识:Seq2Seq模型

Seq2Seq model Seq2Seq&#xff08;Sequence to Sequence&#xff09;模型是一类用于将一个序列转换为另一个序列的深度学习模型&#xff0c;广泛应用于自然语言处理&#xff08;NLP&#xff09;任务&#xff0c;如机器翻译、文本摘要、对话生成等。Seq2Seq模型由编码器&#…

直播预告|飞思实验室暑期公益培训7月10日正式开启,报名从速!

01 培训背景 很荣幸地向大家宣布&#xff1a;卓翼飞思实验室将于7月10日正式开启为期两个月的暑期公益培训&#xff01;本次培训为线上直播&#xff0c;由中南大学计算机学院特聘副教授&#xff0c;RflySim平台总研发负责人戴训华副教授主讲。 培训将基于“RflySim—智能无人…

数据可视化之智慧农业的窗口与引擎

在科技日新月异的今天,农业作为国民经济的基础产业,正逐步向智能化、数字化转型。农业为主题的数据可视化大屏看板,作为这一转型过程中的重要工具,不仅为农业管理者提供了全面、实时的农田信息,还促进了农业资源的优化配置和农业生产效率的提升。本文将深入探讨农业数据可…

Git 运用小知识

1.Git添加未完善代码的解决方法 1.1 Git只是提交未推送 把未完善的代码提交到本地仓库 只需点击撤销提交&#xff0c;提交的未完善代码会被撤回 代码显示未提交状态 1.2 Git提交并推送 把未完善的代码提交并推送到远程仓库 点击【未完善提交并推送】的结点选择还原提交&#x…

最佳 iPhone 解锁软件工具,可免费下载用于电脑操作的

业内专业人士表示&#xff0c;如果您拥有 iPhone&#xff0c;您一定知道忘记锁屏密码会多么令人沮丧。由于 Apple 的安全功能强大&#xff0c;几乎不可能在没有密码或 Apple ID 的情况下访问锁定的 iPhone。 “当我忘记密码时&#xff0c;如何在没有密码的情况下解锁iPhone&am…

银河麒麟V10 SP1 审计工具 auditd更新

前言 银河麒麟V10 SP1 审计工具 auditd 引发的内存占用过高&#xff0c; 内存使用率一直在 60% 以上&#xff0c; 内存一直不释放 排查 可以使用ps或者top查看系统进程使用情况 ps -aux|sort -k4nr|head -n 5 发现银河麒麟审计工具 auditd 一直占用内存不释放 解决 办法一…

Java视频点播网站

作者介绍&#xff1a;计算机专业研究生&#xff0c;现企业打工人&#xff0c;从事Java全栈开发 主要内容&#xff1a;技术学习笔记、Java实战项目、项目问题解决记录、AI、简历模板、简历指导、技术交流、论文交流&#xff08;SCI论文两篇&#xff09; 上点关注下点赞 生活越过…

基于OpenCv的快速图片颜色交换,轻松实现图片背景更换

图片颜色更换 图片颜色转换 当我们有2张图片,很喜欢第一张图片的颜色,第2张图片的前景照片,很多时候我们需要PS进行图片的颜色转换,这当然需要我们有强大的PS功底,当然小编这里不是介绍PS的,我们使用代码完全可以代替PS 进行图片的颜色转换 图片颜色转换步骤: 步骤…

智慧校园-教职工管理系统总体概述

在当今信息化时代&#xff0c;智慧校园教职工管理系统成为了提升教育机构管理效能的重要工具。该系统巧妙融合了先进的信息技术&#xff0c;为教职工的日常管理带来了一场静悄悄的革命。它不仅是一个信息存储库&#xff0c;记录着每位教职工从加入到离开的完整职业轨迹&#xf…

AI 与数据的智能融合丨大模型时代下的存储系统

WOT 全球技术创新大会2024北京站于 6 月 22 日圆满落幕。本届大会以“智启新纪&#xff0c;慧创万物”为主题&#xff0c;邀请到 60 位不同行业的专家&#xff0c;聚焦 AIGC、领导力、研发效能、架构演进、大数据等热门技术话题进行分享。 近年来&#xff0c;数据和人工智能已…

3.pwn 函数调用流程,调用约定

前置准备 pop: Pop指令的作用是弹栈&#xff0c;将栈顶的数据弹出到寄存器&#xff0c;然后栈顶指针向下移动一个单位。 具体来说:如pop rax&#xff0c;作用就是mov rax[rsp];add rsp 8; push: Push指令的作用就是压栈&#xff0c;将栈顶指针向上移动一个单位的距离&#xf…

如何使用uer做多分类任务

如何使用uer做多分类任务 语料集下载 找到这里点击即可 里面是这有json文件的 因此我们对此要做一些处理&#xff0c;将其转为tsv格式 # -*- coding: utf-8 -*- import json import csv import chardet# 检测文件编码 def detect_encoding(file_path):with open(file_path,…

【已解决】“import ... =“ 只能在 TypeScript 文件中使用

现象 在使用 import 语法的时候&#xff0c;代码报红&#xff0c;提示&#xff1a;“import ... “ 只能在 TypeScript 文件中使用 原因 代码被 VSCode 解析成 TypeScript 语法 解决方案&#xff1a; 关闭 JavaScript 的验证启用即可。 mac 快捷方式&#xff1a;comman s…

秋招突击——7/4——复习{}——新作{最长公共子序列、编辑距离、买股票最佳时机、跳跃游戏}

文章目录 引言复习新作1143-最长公共子序列个人实现 参考实现编辑距离个人实现参考实现 贪心——买股票的最佳时机个人实现参考实现 贪心——55-跳跃游戏个人实现参考做法 总结 引言 昨天主要是面试&#xff0c;然后剩下的时间都是用来对面试中不会的东西进行查漏补缺&#xff…

蓝桥杯web组国三选手题纲解析和备赛技巧--经验分享

蓝桥杯web组赛题解析和杯赛技巧 **&#x1f389;&#x1f389;&#x1f389;欢迎来到我的博客,我是一名自学了2年半前端的大一学生,熟悉的技术是JavaScript与Vue.目前正在往全栈方向前进, 如果我的博客给您带来了帮助欢迎您关注我,我将会持续不断的更新文章!!!&#x1f64f;&am…

51单片机嵌入式开发:2、STC89C52操作GPIO口LED灯

STC89C52操作GPIO口LED灯 1 芯片介绍1.1 芯片类型1.2 芯片系列说明 2 GPIO引脚寄存器说明3 GPIO操作3.1 GPIO输入3.2 GPIO输出3.3 GPIO流水灯3.4 Protues仿真 4 总结 1 芯片介绍 1.1 芯片类型 芯片采用宏晶科技品牌下的STC89C52RC单片机 选择STC89C52RC系列STC89C58RD系列单片…