Android11.0(R) 华为充电动画

news/2024/11/13 4:30:07/

根据系统原有的无线充电动画流程,新增有线充电气泡动画。

效果图

hU8zcD.png

修改文件清单

	vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.javavendor/mediatek/proprietary/packages/apps/SystemUI/res/layout/wired_charging_layout.xmlvendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/charging/BubbleBean.javavendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/charging/BubbleViscosity.javavendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/charging/WiredChargingAnimation.java

具体实现

新增布局
vendor/mediatek/proprietary/packages/apps/SystemUI/res/layout/wired_charging_layout.xml

<FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/shcy_charge_view"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#99000000"><com.android.systemui.charging.BubbleViscosityandroid:id="@+id/shcy_bubble_view"android:layout_width="match_parent"android:layout_height="match_parent"/>
</FrameLayout>

新增气泡 bean
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/charging/BubbleBean.java

package com.android.systemui.charging;public class BubbleBean {private float randomY = 3;private float x;private float y;private int index;public BubbleBean(float x, float y, float randomY, int index) {this.x = x;this.y = y;this.randomY = randomY;this.index = index;}public void set(float x, float y, float randomY, int index) {this.x = x;this.y = y;this.randomY = randomY;this.index = index;}public void setMove(int screenHeight, int maxDistance) {if (y - maxDistance < 110) {this.y -= 2;return;}if (maxDistance <= y && screenHeight - y > 110) {this.y -= randomY;} else {this.y -= 0.6;}if (index == 0) {this.x -= 0.4;} else if (index == 2) {this.x += 0.4;}}public int getIndex() {return index;}public float getX() {return x;}public void setX(float x) {this.x = x;}public float getY() {return y;}public void setY(float y) {this.y = y;}
}

新增充电动画自定义 view
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/charging/BubbleViscosity.java

package com.android.systemui.charging;import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.SurfaceHolder;
import android.view.SurfaceView;public class BubbleViscosity extends SurfaceView implementsSurfaceHolder.Callback, Runnable {private static ScheduledExecutorService scheduledThreadPool;private Context context;private String paintColor = "#25DA29";private String centreColor = "#00000000";private String minCentreColor = "#9025DA29";private int screenHeight;private int screenWidth;private float lastRadius;private float rate = 0.32f;private float rate2 = 0.45f;private PointF lastCurveStrat = new PointF();private PointF lastCurveEnd = new PointF();private PointF centreCirclePoint = new PointF();private float centreRadius;private float bubbleRadius;private PointF[] arcPointStrat = new PointF[8];private PointF[] arcPointEnd = new PointF[8];private PointF[] control = new PointF[8];private PointF arcStrat = new PointF();private PointF arcEnd = new PointF();private PointF controlP = new PointF();List<PointF> bubbleList = new ArrayList<>();List<BubbleBean> bubbleBeans = new ArrayList<>();private int rotateAngle = 0;private float controlrate = 1.66f;private float controlrateS = 1.3f;private int i = 0;private SurfaceHolder mHolder;private float scale = 0;private Paint arcPaint;private Paint minCentrePaint;private Paint bubblePaint;private Paint centrePaint;private Paint lastPaint;private Path lastPath;private Random random;private Paint textPaint;private String text = "78 %";private Rect rect;public BubbleViscosity(Context context) {this(context, null);}public BubbleViscosity(Context context, AttributeSet attrs) {this(context, attrs, 0);}public BubbleViscosity(Context context, AttributeSet attrs,int defStyleAttr) {super(context, attrs, defStyleAttr);this.context = context;initTool();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);screenHeight = getMeasuredHeight();screenWidth = getMeasuredWidth();}private void initTool() {rect = new Rect();mHolder = getHolder();mHolder.addCallback(this);setFocusable(true);mHolder.setFormat(PixelFormat.TRANSPARENT);setZOrderOnTop(true);lastRadius = dip2Dimension(40f, context);centreRadius = dip2Dimension(100f, context);bubbleRadius = dip2Dimension(15f, context);random = new Random();lastPaint = new Paint();lastPaint.setAntiAlias(true);lastPaint.setStyle(Paint.Style.FILL);lastPaint.setColor(Color.parseColor(paintColor));lastPaint.setStrokeWidth(2);lastPath = new Path();centrePaint = new Paint();centrePaint.setAntiAlias(true);centrePaint.setStyle(Paint.Style.FILL);centrePaint.setStrokeWidth(2);centrePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));centrePaint.setColor(Color.parseColor(centreColor));arcPaint = new Paint();arcPaint.setAntiAlias(true);arcPaint.setStyle(Paint.Style.FILL);arcPaint.setColor(Color.parseColor(paintColor));arcPaint.setStrokeWidth(2);minCentrePaint = new Paint();minCentrePaint.setAntiAlias(true);minCentrePaint.setStyle(Paint.Style.FILL);minCentrePaint.setColor(Color.parseColor(minCentreColor));minCentrePaint.setStrokeWidth(2);bubblePaint = new Paint();bubblePaint.setAntiAlias(true);bubblePaint.setStyle(Paint.Style.FILL);bubblePaint.setColor(Color.parseColor(minCentreColor));bubblePaint.setStrokeWidth(2);textPaint = new Paint();textPaint.setAntiAlias(true);textPaint.setStyle(Paint.Style.FILL);textPaint.setColor(Color.parseColor("#FFFFFF"));textPaint.setStrokeWidth(2);textPaint.setTextSize(dip2Dimension(40f, context));}private void onMDraw() {Canvas canvas = mHolder.lockCanvas();canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);bubbleDraw(canvas);lastCircleDraw(canvas);centreCircleDraw(canvas);textPaint.getTextBounds(text, 0, text.length(), rect);canvas.drawText(text, centreCirclePoint.x - rect.width() / 2,centreCirclePoint.y + rect.height() / 2, textPaint);mHolder.unlockCanvasAndPost(canvas);}public void setBatteryLevel(String level){this.text=level+"%";postInvalidate();}private void centreCircleDraw(Canvas canvas) {centreCirclePoint.set(screenWidth / 2, screenHeight / 2);circleInCoordinateDraw(canvas);canvas.drawCircle(centreCirclePoint.x, centreCirclePoint.y,centreRadius, centrePaint);}private void lastCircleDraw(Canvas canvas) {lastCurveStrat.set(screenWidth / 2 - lastRadius, screenHeight);lastCurveEnd.set((screenWidth / 2), screenHeight);float k = (lastRadius / 2) / lastRadius;float aX = lastRadius - lastRadius * rate2;float aY = lastCurveStrat.y - aX * k;float bX = lastRadius - lastRadius * rate;float bY = lastCurveEnd.y - bX * k;lastPath.rewind();lastPath.moveTo(lastCurveStrat.x, lastCurveStrat.y);lastPath.cubicTo(lastCurveStrat.x + aX, aY, lastCurveEnd.x - bX, bY,lastCurveEnd.x, lastCurveEnd.y - lastRadius / 2);lastPath.cubicTo(lastCurveEnd.x + bX, bY, lastCurveEnd.x + lastRadius- aX, aY, lastCurveEnd.x + lastRadius, lastCurveEnd.y);lastPath.lineTo(lastCurveStrat.x, lastCurveStrat.y);canvas.drawPath(lastPath, lastPaint);}private int bubbleIndex = 0;private void bubbleDraw(Canvas canvas) {for (int i = 0; i < bubbleBeans.size(); i++) {if (bubbleBeans.get(i).getY() <= (int) (screenHeight / 2 + centreRadius)) {bubblePaint.setAlpha(000);canvas.drawCircle(bubbleBeans.get(i).getX(), bubbleBeans.get(i).getY(), bubbleRadius, bubblePaint);} else {bubblePaint.setAlpha(150);canvas.drawCircle(bubbleBeans.get(i).getX(), bubbleBeans.get(i).getY(), bubbleRadius, bubblePaint);}}}/*** @param dip* @param context* @return*/public float dip2Dimension(float dip, Context context) {DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip,displayMetrics);}/*** @param canvas*/public void circleInCoordinateDraw(Canvas canvas) {int angle;for (int i = 0; i < arcPointStrat.length; i++) {if (i > 3 && i < 6) {if (i == 4) {angle = rotateAngle + i * 60;} else {angle = rotateAngle + i * 64;}} else if (i > 5) {if (i == 6) {angle = rotateAngle + i * 25;} else {angle = rotateAngle + i * 48;}} else {angle = rotateAngle + i * 90;}float radian = (float) Math.toRadians(angle);float adjacent = (float) Math.cos(radian) * centreRadius;float right = (float) Math.sin(radian) * centreRadius;float radianControl = (float) Math.toRadians(90 - (45 + angle));float xStrat = (float) Math.cos(radianControl) * centreRadius;float yEnd = (float) Math.sin(radianControl) * centreRadius;if (i == 0 || i == 1) {if (i == 1) {arcStrat.set(centreCirclePoint.x + adjacent - scale,centreCirclePoint.y + right + scale);arcEnd.set(centreCirclePoint.x - right, centreCirclePoint.y+ adjacent);} else {arcStrat.set(centreCirclePoint.x + adjacent,centreCirclePoint.y + right);arcEnd.set(centreCirclePoint.x - right - scale,centreCirclePoint.y + adjacent + scale);}controlP.set(centreCirclePoint.x + yEnd * controlrate,centreCirclePoint.y + xStrat * controlrate);} else {arcStrat.set(centreCirclePoint.x + adjacent,centreCirclePoint.y + right);arcEnd.set(centreCirclePoint.x - right, centreCirclePoint.y+ adjacent);if (i > 5) {controlP.set(centreCirclePoint.x + yEnd * controlrateS,centreCirclePoint.y + xStrat * controlrateS);} else {controlP.set(centreCirclePoint.x + yEnd * controlrate,centreCirclePoint.y + xStrat * controlrate);}}arcPointStrat[i] = arcStrat;arcPointEnd[i] = arcEnd;control[i] = controlP;lastPath.rewind();lastPath.moveTo(arcPointStrat[i].x, arcPointStrat[i].y);lastPath.quadTo(control[i].x, control[i].y, arcPointEnd[i].x,arcPointEnd[i].y);if (i > 3 && i < 6) {canvas.drawPath(lastPath, minCentrePaint);} else {canvas.drawPath(lastPath, arcPaint);}lastPath.rewind();}}private void setAnimation() {setScheduleWithFixedDelay(this, 0, 5);setScheduleWithFixedDelay(new Runnable() {@Overridepublic void run() {if (bubbleIndex > 2)bubbleIndex = 0;if (bubbleBeans.size() < 8) {bubbleBeans.add(new BubbleBean(bubbleList.get(bubbleIndex).x, bubbleList.get(bubbleIndex).y, random.nextInt(4) + 2,bubbleIndex));} else {for (int i = 0; i < bubbleBeans.size(); i++) {if (bubbleBeans.get(i).getY() <= (int) (screenHeight / 2 + centreRadius)) {bubbleBeans.get(i).set(bubbleList.get(bubbleIndex).x,bubbleList.get(bubbleIndex).y,random.nextInt(4) + 2, bubbleIndex);if (random.nextInt(bubbleBeans.size()) + 3 == 3 ? true: false) {} else {break;}}}}bubbleIndex++;}}, 0, 300);}private static ScheduledExecutorService getInstence() {if (scheduledThreadPool == null) {synchronized (BubbleViscosity.class) {if (scheduledThreadPool == null) {scheduledThreadPool = Executors.newSingleThreadScheduledExecutor();}}}return scheduledThreadPool;}private static void setScheduleWithFixedDelay(Runnable var1, long var2,long var4) {getInstence().scheduleWithFixedDelay(var1, var2, var4,TimeUnit.MILLISECONDS);}public static void onDestroyThread() {getInstence().shutdownNow();if (scheduledThreadPool != null) {scheduledThreadPool = null;}}@Overridepublic void surfaceCreated(SurfaceHolder holder) {bubbleList.clear();setBubbleList();startBubbleRunnable();setAnimation();}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {onDestroyThread();}@Overridepublic void run() {i++;rotateAngle = i;if (i > 90 && i < 180) {scale += 0.25;if (controlrateS < 1.66)controlrateS += 0.005;} else if (i >= 180) {scale -= 0.12;if (i > 300)controlrateS -= 0.01;}onMDraw();if (i == 360) {i = 0;rotateAngle = 0;controlrate = 1.66f;controlrateS = 1.3f;scale = 0;}}public void setBubbleList() {float radian = (float) Math.toRadians(35);float adjacent = (float) Math.cos(radian) * lastRadius / 3;float right = (float) Math.sin(radian) * lastRadius / 3;if (!bubbleList.isEmpty())return;bubbleList.add(new PointF(screenWidth / 2 - adjacent, screenHeight- right));bubbleList.add(new PointF(screenWidth / 2, screenHeight - lastRadius/ 4));bubbleList.add(new PointF(screenWidth / 2 + adjacent, screenHeight- right));startBubbleRunnable();}public void startBubbleRunnable(){setScheduleWithFixedDelay(new Runnable() {@Overridepublic void run() {for (int i = 0; i < bubbleBeans.size(); i++) {bubbleBeans.get(i).setMove(screenHeight,(int) (screenHeight / 2 + centreRadius));}}}, 0, 4);}
}

新增动画管理类
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/charging/WiredChargingAnimation.java

package com.android.systemui.charging;import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.util.Slog;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.view.LayoutInflater;
import com.android.systemui.R;public class WiredChargingAnimation {public static final long DURATION = 3333;private static final String TAG = "WiredChargingAnimation";private static final boolean DEBUG = true || Log.isLoggable(TAG, Log.DEBUG);private final WiredChargingView mCurrentWirelessChargingView;private static WiredChargingView mPreviousWirelessChargingView;private static boolean mShowingWiredChargingAnimation;public static boolean isShowingWiredChargingAnimation(){return mShowingWiredChargingAnimation;}public WiredChargingAnimation(@NonNull Context context, @Nullable Looper looper, intbatteryLevel,  boolean isDozing) {mCurrentWirelessChargingView = new WiredChargingView(context, looper,batteryLevel, isDozing);}public static WiredChargingAnimation makeWiredChargingAnimation(@NonNull Context context,@Nullable Looper looper, int batteryLevel, boolean isDozing) {mShowingWiredChargingAnimation = true;android.util.Log.d(TAG,"makeWiredChargingAnimation batteryLevel="+batteryLevel);return new WiredChargingAnimation(context, looper, batteryLevel, isDozing);}/*** Show the view for the specified duration.*/public void show() {if (mCurrentWirelessChargingView == null ||mCurrentWirelessChargingView.mNextView == null) {throw new RuntimeException("setView must have been called");}/*if (mPreviousWirelessChargingView != null) {mPreviousWirelessChargingView.hide(0);}*/mPreviousWirelessChargingView = mCurrentWirelessChargingView;mCurrentWirelessChargingView.show();mCurrentWirelessChargingView.hide(DURATION);}private static class WiredChargingView {private static final int SHOW = 0;private static final int HIDE = 1;private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();private final Handler mHandler;private int mGravity;private View mView;private View mNextView;private WindowManager mWM;public WiredChargingView(Context context, @Nullable Looper looper, int batteryLevel, boolean isDozing) {//mNextView = new WirelessChargingLayout(context, batteryLevel, isDozing);mNextView = LayoutInflater.from(context).inflate(R.layout.wired_charging_layout, null, false);BubbleViscosity shcyBubbleViscosity = mNextView.findViewById(R.id.shcy_bubble_view);shcyBubbleViscosity.setBatteryLevel(batteryLevel+"");mGravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER;final WindowManager.LayoutParams params = mParams;params.height = WindowManager.LayoutParams.MATCH_PARENT;params.width = WindowManager.LayoutParams.MATCH_PARENT;params.format = PixelFormat.TRANSLUCENT;params.type = WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;params.setTitle("Charging Animation");params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE| WindowManager.LayoutParams.FLAG_DIM_BEHIND;params.dimAmount = .3f;if (looper == null) {// Use Looper.myLooper() if looper is not specified.looper = Looper.myLooper();if (looper == null) {throw new RuntimeException("Can't display wireless animation on a thread that has not called "+ "Looper.prepare()");}}mHandler = new Handler(looper, null) {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case SHOW: {handleShow();break;}case HIDE: {handleHide();// Don't do this in handleHide() because it is also invoked by// handleShow()mNextView = null;mShowingWiredChargingAnimation = false;break;}}}};}public void show() {if (DEBUG) Slog.d(TAG, "SHOW: " + this);mHandler.obtainMessage(SHOW).sendToTarget();}public void hide(long duration) {mHandler.removeMessages(HIDE);if (DEBUG) Slog.d(TAG, "HIDE: " + this);mHandler.sendMessageDelayed(Message.obtain(mHandler, HIDE), duration);}private void handleShow() {if (DEBUG) {Slog.d(TAG, "HANDLE SHOW: " + this + " mView=" + mView + " mNextView="+ mNextView);}if (mView != mNextView) {// remove the old view if necessaryhandleHide();mView = mNextView;Context context = mView.getContext().getApplicationContext();String packageName = mView.getContext().getOpPackageName();if (context == null) {context = mView.getContext();}mWM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);mParams.packageName = packageName;mParams.hideTimeoutMilliseconds = DURATION;if (mView.getParent() != null) {if (DEBUG) Slog.d(TAG, "REMOVE! " + mView + " in " + this);mWM.removeView(mView);}if (DEBUG) Slog.d(TAG, "ADD! " + mView + " in " + this);try {mWM.addView(mView, mParams);} catch (WindowManager.BadTokenException e) {Slog.d(TAG, "Unable to add wireless charging view. " + e);}}}private void handleHide() {if (DEBUG) Slog.d(TAG, "HANDLE HIDE: " + this + " mView=" + mView);if (mView != null) {if (mView.getParent() != null) {if (DEBUG) Slog.d(TAG, "REMOVE! " + mView + " in " + this);mWM.removeViewImmediate(mView);}mView = null;}}}
}

电源插入时且在锁屏下显示气泡动画

vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java

//cczheng add for hw charge start 
import com.android.systemui.charging.WiredChargingAnimation;
//cczheng add for hw charge endmBatteryController.addCallback(new BatteryStateChangeCallback() {@Overridepublic void onPowerSaveChanged(boolean isPowerSave) {mHandler.post(mCheckBarModes);if (mDozeServiceHost != null) {mDozeServiceHost.firePowerSaveChanged(isPowerSave);}}@Overridepublic void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {// noop//cczheng add for hw charge start    boolean isShowing = WiredChargingAnimation.isShowingWiredChargingAnimation();android.util.Log.d("WiredChargingAnimation","level="+level+" charging="+charging+" isShowing="+isShowing);if (!isShowing && charging && mState == StatusBarState.KEYGUARD) {WiredChargingAnimation.makeWiredChargingAnimation(mContext, null,level, false).show();}//cczheng add for hw charge end}});

http://www.ppmy.cn/news/721752.html

相关文章

【maven】安装、使用和常用命令

安装 windows 下载Maven二进制文件 前往Apache Maven官方网站 (https://maven.apache.org) &#xff0c;找到最新的稳定版本&#xff0c;然后下载对应的二进制压缩包&#xff08;如apache-maven-3.8.2-bin.zip&#xff09;。解压缩文件 将下载的压缩包解压到你选择的目录&…

[每日一水] Latex Tikz foreach 循环嵌套

\documentclass{article} \usepackage{tikz} \begin{document} \begin{tikzpicture} \foreach[count\i] \x in {20,18,...,2}\foreach[count\j] \y in {20,18,...,2}\node at (\i,\j) {\x \y}; \end{tikzpicture} \end{document}\node at (\i,\j) {\x \y}; 就是写文本的意思

【Django】在Linux上部署Django(nginx+uwsgi)

1.说明 关于在Linux上使用uwsgi部署Django的项目的过程并不难&#xff0c;主要是配置文件的写法&#xff0c;尤其是nginx的配置文件&#xff0c;本文在Ubuntu20.04上通过uwsgi和nginx部署Django项目 2.安装环境 安装环境主要有Nginx、Python、MySQL、Redis&#xff0c;可以根…

我在神奇代码岛研究了一点辅助功能

// UserScript // name BoxMap // namespace http://tampermonkey.net/ // version 0.1 // description 帮助萌新快速了解Box3.0 // author 云游的残梦 饼干盒协助 // match https://box3.codemao.cn/* // icon https://static.box3.c…

20年了啊:那年冬天

雪一片一片一片一片&#xff0c;让我想起二十年前。那时我还是一张白纸&#xff0c;不带伞的少年&#xff0c;幸运的进入了一家公司&#xff0c;开始了我的北京都市生活。 公司在国贸附近&#xff0c;是北京有名的商务白领区。写字楼出出进进到处是一年四季都不穿裤子的女孩和女…

面试06,[长亮科技]()(offer)、[荔枝]()FM(在确定部门和薪资)、[涂鸦智能]()(第一轮电话面半小时,待后续)、华资软件(HR面)、[广州速游]()(已挂)。至于公司怎么样不加以言论。

作者&#xff1a;Carson-Zhao 链接&#xff1a;https://ac.nowcoder.com/discuss/522002?type2&order0&pos16&page1&ncTraceId&channel-1&source_iddiscuss_tag_nctrack 来源&#xff1a;牛客网 总结一下这几天的面试吧&#xff01;从19号到现在23号…

零食社交 or 甜蜜陷阱?说说公司那些免费提供的零食饮料

很多公司都提供免费的零食、水果和饮料。说起来是件轻松愉快的事情&#xff0c;可是&#xff0c;偏偏有人因为这些小福利离职&#xff0c;还有人因为它们损害了健康……对于这些随便吃、随便喝、随便拿的东西应该采取什么样的态度才能于己有利&#xff1f;很多公司在普通零食之…

第2章 进程的描述与控制

操作系统 第2章 进程的描述与控制2.2 进程的描述2.2.3 挂起操作和进程状态的转换2.2.4 进程管理中的数据结构 2.3 进程控制2.3.1 操作系统内核2.3.2 进程的创建2.3.3 进程的终止2.3.4 进程的阻塞与唤醒&#xff08;浅学一下&#xff09;2.3.5 进程的挂起与激活&#xff08;浅学…