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{}@Overridepublic 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{}@Overridepublic 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");}@Overridepublic 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";}@Overridepublic void registerCallback(ICallBack callback) throws RemoteException {callbackList.register(callback);Log.d(TAG, "registerCallback() called with: callback = [" + callback + "]");}@Overridepublic 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

 	@Overridepublic 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 theerrors above.2) You can update current.txt by executing the following command:make update-apiTo 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() {@Overridepublic void onReceive(String serverMsg) throws RemoteException {Log.d(TAG, "onReceive() called with: serverMsg = [" + serverMsg + "]");}};@Overrideprotected 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() {@Overridepublic void onReceive(String serverMsg) throws RemoteException {Log.d(TAG, "onReceive() called with: serverMsg = [" + serverMsg + "]");}};@Overrideprotected 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.pswp.cn/web/40962.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/40962.shtml
英文地址,請注明出處:http://en.pswp.cn/web/40962.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

墨烯的C語言技術棧-C語言基礎-007

七.字符串 由雙引號引起的一串字符稱為字符串字面值,或者簡稱字符串 字符串的結束標志是"\0" int main() { //#qWer$ //char 字符類型 //a; //char ch "w"; //字符串 //C語言中沒有字符串類型 "abcdefg"; char arr1[] "abc…

柯橋職場英語學習商務英語口語生活英語培訓生活口語學習

辣妹用英語怎么說&#xff1f; 辣妹在英語中通常被翻譯為“hot girl”或“spicy girl”&#xff0c;但更常見和直接的是“hot chick”或簡單地使用“hot”來形容。 舉個例子: Shes a real hot girl with her trendy outfit and confident attitude. 她真是個辣妹&#xff0…

Redis---10---SpringBoot集成Redis

SpringBoot集成Redis 總體概述jedis-lettuce-RedisTemplate三者的聯系 本地Java連接Redis常見問題&#xff0c;注意 bind配置請注釋掉? 保護模式設置為no? Linux系統的防火墻設置? redis服務器的IP地址和密碼是否正確? 忘記寫訪問redis的服務端口號和auth密碼集成Jedis …

Docker:Docker網絡

Docker Network 是 Docker 平臺中的一項功能&#xff0c;允許容器相互通信以及與外界通信。它提供了一種在 Docker 環境中創建和管理虛擬網絡的方法。Docker 網絡使容器能夠連接到一個或多個網絡&#xff0c;從而使它們能夠安全地共享信息和資源。 預備知識 推薦先看視頻先有…

最長公共子序列求長度和輸出子序列C代碼

求兩個字符串的公共子序列我們都知道需要使用用動態規劃思想 用res[i][j]表示截止到字符串A的第i個字符串和截止到字符串B的第j個字符的最長公共子序列。如兩個字符串helloworld和loop&#xff0c;res[5][3]表示子串hello和子串loo的最長公共子序列&#xff0c;為lo&#xff0…

2024機器人科研/研發領域最新研究方向崗位職責與要求

具身智能工程師 從事具身智能領域的技術研究或產品開發&#xff0c;制定具身智能技術標準&#xff0c;利用大模型技術來提高機器人的智能化水平&#xff0c;研究端云協同的機器人系統框架&#xff0c;并賦能人形/復合等各類形態的機器人。具體內容包括不限于&#xff1a; 1、負…

maven項目使用netty,前端是vue2,實現通訊

引入的java包 <!-- 以下是即時通訊--><!-- Netty core modules --><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.76.Final</version> <!-- 使用最新的穩定版本…

C++初學者指南-4.診斷---地址檢測器

C初學者指南-4.診斷—地址檢測器 幻燈片 地址檢測器&#xff08;ASan&#xff09; 適用編譯器g,clang檢測內存錯誤 內存泄露訪問已經釋放的內存訪問不正確的堆棧區域 用額外的指令檢測代碼 運行時間增加約70%內存使用量大約增加了3倍 示例&#xff1a;檢測空指針 使用地址…

中英雙語介紹百老匯著名歌劇:《貓》(Cats)和《劇院魅影》(The Phantom of the Opera)

中文版 百老匯著名歌劇 百老匯&#xff08;Broadway&#xff09;是世界著名的劇院區&#xff0c;位于美國紐約市曼哈頓。這里匯集了許多著名的音樂劇和歌劇&#xff0c;吸引了全球各地的觀眾。以下是兩部百老匯的經典音樂劇&#xff1a;《貓》和《劇院魅影》的詳細介紹。 1.…

CP AUTOSAR標準之RAMTest(AUTOSAR_CP_SWS_RAMTest)(更新中……)

1 簡介和功能概述 AUTOSAR基礎軟件模塊“RAM測試”的功能、API和配置。 ??RAM測試是對RAM單元的物理健康狀況的測試。它不是為了測試RAM的內容。用于寄存器的RAM也經過測試。 ??在本文檔中,RAM單元被理解為內存單位,可由處理器單獨尋址。因此,對于16位處理器,單元大小(…

拉普拉斯逆變換

https://www.bilibili.com/video/BV17i4y1475Y?p21&vd_source2e6b4ba548ec9462b2f9633ff700e9b9 CV 17 陳永平教授關于拉普拉斯逆變換的式子的推導 最關鍵的兩步 想到取一個合適的contour L R L_R LR?部分是實部 γ \gamma γ要大于所有極點的實部,這樣就可以搞一個大…

SCI二區TOP|麋鹿群優化算法: 一種新穎的受自然啟發的元啟發式算法

目錄 1.背景2.算法原理2.1算法思想2.2算法過程 3.結果展示4.參考文獻5.代碼獲取 1.背景 2024年&#xff0c;SO Oladejo受到麋鹿群的繁殖過程啟發&#xff0c;提出了麋鹿群優化算法&#xff08;Elk herd optimizer, EHO&#xff09;。 2.算法原理 2.1算法思想 EHO靈感來自麋鹿…

設計外包管理辦法和步驟之HMI

設計外包流程和步驟之人機界面HMI, Human-Machine Interface 1. 源由2. 流程&步驟2.1 明確需求2.2 尋找外包公司2.3 簽訂合同2.4 項目啟動2.5 設計過程2.6 迭代開發2.7 驗收和交付2.8 維護和支持 3. 工具和平臺推薦4. 總結5. 補充 - 需求、交付、驗收5.1 需求5.2 交付5.3 驗…

C語言編程與進階

1.0 C語言關鍵字 1-1C語言關鍵字-CSDN博客文章瀏覽閱讀831次&#xff0c;點贊13次&#xff0c;收藏24次。define使用define定義常量return 0;使用define定義宏// define 定義宏&#xff0c;名字是ADD(x,y),x y 是宏的參數int a 10;int b 20;return 0;宏定義的本質是替換&am…

pandas讀取CSV格式文件生成數據發生器iteration

背景 數據集標簽為csv文件格式&#xff0c;有三個字段column_hander [‘id’, ‘boneage’, ‘male’]&#xff0c;需要自己定義數據集。文件較大&#xff0c;做一個數據發生器迭代更新數據集。 實現模板 在Pandas中&#xff0c;可以使用pandas.read_csv函數讀取CSV文件&…

ShardingSphere實戰

ShardingSphere實戰 文章目錄 ShardingSphere實戰分庫分表實戰建表建表sql利用存儲過程建表Sharding-jdbc分庫分表配置 基于業務的Sharding-key考慮訂單id用戶id分片策略訂單id的設計與實現**設計思想**&#xff1a;設計思路&#xff1a; 具體分片策略實現測試數據插入商戶商品…

推薦好玩的工具之OhMyPosh使用

解除禁止腳本 Set-ExecutionPolicy RemoteSigned 下載Oh My Posh winget install oh-my-posh 或者 Install-Module oh-my-posh -Scope AllUsers 下載Git提示 Install-Module posh-git -Scope CurrentUser 或者 Install-Module posh-git -Scope AllUser 下載命令提示 Install-Mo…

SwinUnet詳解

文章目錄 摘要一. 編碼端模塊1. PatchEmbed2. SwinTransformerBlock2.1. Window_partition2.2. WindowAttention2.3. Window_reverse2.4. MLP 3. PatchMerging 二. 解碼端模塊三. 完整流程圖 摘要 swinunet基本結構&#xff1a; swinunet采用編碼器-解碼器結構&#xff1a; 編…

5、MP4解復用---AAC+H264

MP4 MP4同樣是一種容器格式&#xff0c;是由一個一個Box組成&#xff0c;每個Box又分為Header與Data&#xff0c;Data又包含很多子Box&#xff0c;具體的MP4文件結構也看過&#xff0c;內部Box結構比較復雜&#xff0c;一般不寫MP4解釋器的話&#xff0c;Box結構不用了解太細&a…

.NET編程:C#下WinForms多語種切換的藝術

概述 在全球化的今天&#xff0c;軟件的多語言支持已成為標配。.NET中的WinForms應用程序提供了多種方式來實現多語種切換&#xff0c;讓軟件能夠跨越語言障礙&#xff0c;觸及更廣闊的用戶群體。本文將帶領大家探索C#下WinForms應用程序實現多語種切換的不同方法&#xff0c;通…