学习Android的第二十五天

目录

Android TextWatcher

范例

参考文档

Android 消息传递 - Handler

Handler的工作机制

Handler 方法

范例

参考文档

Android AsyncTask 异步任务

什么是多线程

同步与异步

Android 为什么要引入异步任务

AsyncTask

AsyncTask 方法与流程

范例

参考文档


Android TextWatcher

要监听 EditText 中文本内容的变化,可以使用 TextWatcher。

TextWatcher 是一个接口,TextWatcher 接口包含了三个方法,分别用于监听文本内容变化的不同阶段。(一般重写得较多的是第三个方法)

  • beforeTextChanged(CharSequence s, int start, int count, int after):在文本内容发生改变之前被调用。可以用来获取改变前的文本内容等信息。
  • onTextChanged(CharSequence s, int start, int before, int count):在文本内容发生改变时被调用。可以用来执行一些实时监测或处理文本变化的逻辑。
  • afterTextChanged(Editable s):在文本内容发生改变之后被调用。通常用于处理最终的文本内容,比如输入验证、搜索操作等。

范例

首先,在 XML 布局文件中添加自定义的 EditText:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><com.example.myapplication2.ClearableEditTextandroid:id="@+id/editText"android:layout_width="match_parent"android:layout_height="wrap_content"/></RelativeLayout>

然后,在 Java 代码中创建 ClearableEditText 类并继承 EditText

package com.example.myapplication2;import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;import androidx.appcompat.widget.AppCompatEditText;
import androidx.core.content.ContextCompat;public class ClearableEditText extends AppCompatEditText {private Drawable clearDrawable; // 清空按钮的图标public ClearableEditText(Context context) {super(context);init();}public ClearableEditText(Context context, AttributeSet attrs) {super(context, attrs);init();}public ClearableEditText(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}// 初始化方法private void init() {// 设置清空按钮图标clearDrawable = ContextCompat.getDrawable(getContext(), R.drawable.baseline_block_24);if (clearDrawable != null) {clearDrawable.setBounds(0, 0, clearDrawable.getIntrinsicWidth(), clearDrawable.getIntrinsicHeight());}setClearIconVisible(false); // 初始时隐藏清空按钮addTextChangedListener(textWatcher); // 监听文本变化setOnTouchListener(touchListener); // 监听触摸事件}// 文本变化监听器private TextWatcher textWatcher = new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {setClearIconVisible(s.length() > 0); // 根据文本长度显示/隐藏清空按钮}@Overridepublic void afterTextChanged(Editable s) {}};// 触摸事件监听器private OnTouchListener touchListener = new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {final int x = (int) event.getX();if (clearDrawable.isVisible() && x > getWidth() - getPaddingRight() - clearDrawable.getIntrinsicWidth()) {if (event.getAction() == MotionEvent.ACTION_UP) {setText(""); // 点击清空按钮时清空文本框内容}return true;}return false;}};// 设置清空按钮可见性private void setClearIconVisible(boolean visible) {setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1],visible ? clearDrawable : null, getCompoundDrawables()[3]);}
}

参考文档

  1. Android TextWatcher

Android 消息传递 - Handler

在Android开发中,Handler是一个非常核心的组件,用于在不同线程之间传递消息,尤其是用于在后台线程和主UI线程之间进行通信。它使得我们能够将一些耗时的操作放在后台线程进行,而在操作完成后能够安全地更新UI。

Handler的工作机制

Handler依赖于两个重要的组件:MessageQueue(消息队列)和Looper(循环处理器)。每个线程可以拥有一个Looper对象,该对象会循环地从MessageQueue中取出消息,并将这些消息分发给目标Handler处理。

  1. MessageQueue:一个线程中的消息存储队列,用于存放所有通过Handler发送的消息(Message)或者执行的任务(Runnable)。
  2. Looper:负责循环地从MessageQueue中读取消息,并将其分发给对应的Handler处理。主线程默认会有一个Looper在运行。
  3. Handler:用于发送和处理消息。可以将消息或任务投递到MessageQueue中,并且可以处理从MessageQueue中接收到的消息。

Handler 方法

在Android开发中,Handler类提供了一系列方法用于消息的发送和处理。这些方法使得Handler成为了线程间通信和UI更新的强大工具。

下面是一些核心方法的详细说明:

处理消息

  • void handleMessage(Message msg): 这是一个需要被重写的方法,用于定义当消息被分发给该Handler时应该执行的动作。这个方法运行在绑定的Looper所在的线程中,通常是主线程。

发送消息

  • sendEmptyMessage(int what): 发送一个包含what字段的空消息到消息队列中,以便立即被处理。这个方法通常用于触发不需要额外数据传递的操作。
  • sendEmptyMessageDelayed(int what, long delayMillis): 发送一个空消息,并指定延迟多少毫秒后消息才会被添加到消息队列中。这个方法可以用于需要延时执行的操作。
  • sendMessage(Message msg): 立即发送一个Message实例到消息队列中。这个方法允许你发送包含数据的消息,通过Message对象的属性来传递数据。
  • sendMessageDelayed(Message msg, long delayMillis): 发送一个Message实例到消息队列中,并指定延迟多少毫秒后消息才会被添加到消息队列中。这个方法用于需要延时执行且需要传递数据的操作。

检查消息

  • boolean hasMessages(int what): 检查消息队列中是否存在what属性为指定值的消息。这个方法可以用于判断是否已经发送了某个特定的消息。
  • boolean hasMessages(int what, Object object): 除了检查what属性外,还会检查消息携带的对象是否为指定对象。这个方法提供了更精确的消息检查机制。

移除消息

  • removeMessages(int what): 从消息队列中移除所有what属性为指定值的消息。这个方法通常用于取消之前发送的某些消息。
  • removeCallbacksAndMessages(Object token): 移除所有与特定token关联的回调和消息。如果token为null,则移除该Handler的所有回调和消息。这个方法对于清理和避免内存泄漏非常有用。

范例

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"><TextViewandroid:id="@+id/timerTextView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="30sp"android:text="0" />
</LinearLayout>
package com.example.myapplication2;import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private int counter = 0;private TextView timerTextView;private Handler handler = new Handler(Looper.getMainLooper());@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);timerTextView = findViewById(R.id.timerTextView);// 启动后台线程进行计时new Thread(new Runnable() {@Overridepublic void run() {while (true) {try {Thread.sleep(1000); // 暂停1秒} catch (InterruptedException e) {e.printStackTrace();}counter++;// 使用Handler更新UIhandler.post(new Runnable() {@Overridepublic void run() {timerTextView.setText(String.valueOf(counter));}});}}}).start();}
}

在这个例子中,我们首先定义了一个counter变量来记录计时器的值,以及一个TextView来显示这个值。接着,我们在onCreate方法中启动了一个新的线程,这个线程每隔一秒就会增加counter的值,并使用handler来更新UI上TextView的显示内容。

参考文档

  1. Android Handler

Android AsyncTask 异步任务

AsyncTask是Android提供的一个抽象类,用于简化在后台线程上执行长时间运行的任务,并在执行完毕后更新UI的过程。它允许执行后台操作并在UI线程上发布结果,而不需要操作线程或处理Handler。

什么是多线程

多线程是现代编程中一个非常重要的概念,它允许程序同时执行多个任务。为了更好地理解多线程,我们需要先明白应用程序、进程和线程这几个基本概念。

应用程序(Application):应用程序是为了完成特定任务,用某种编程语言编写的一组指令集合。这些指令以静态代码的形式存在,当它们被执行时,会变成一个或多个进程。

进程(Process):进程是运行中的程序。它是系统进行资源分配和调度的基本单位。操作系统为每个进程分配独立的内存空间,确保它可以顺序地执行代码。从概念上讲,进程是程序的动态执行过程,包括代码加载、执行和执行完毕等阶段。

线程(Thread):线程是比进程更小的执行单元。一个进程可以包含多个线程,每个线程都共享进程的资源,如内存和文件句柄等,但是每个线程有自己的执行路径。线程由程序负责管理,而进程则是由操作系统调度的。

多线程(Multithreading):多线程指的是在一个进程中并行地执行多条指令。通过操作系统的调度算法,CPU的时间片被分配给不同的线程执行。实际上,由于CPU切换线程的速度非常快,虽然在任意给定的瞬间只有一个线程在执行,但用户感觉就像是多个线程在同时执行一样。

多线程的优点

  • 提高效率:多线程允许程序同时执行多个任务,从而提高应用程序的响应速度和性能。
  • 更好的CPU利用率:通过并行处理,多线程可以使得CPU资源得到更充分的利用。
  • 改善用户体验:在图形用户界面(GUI)应用程序中,多线程可以防止长时间运行的任务阻塞主线程,从而避免界面冻结,提高用户体验。

多线程的挑战
尽管多线程带来了许多好处,但它也引入了一些复杂性和挑战。

  • 线程安全:当多个线程访问共享资源时,需要确保数据的一致性和完整性,避免出现数据竞争(Race Condition)的问题。
  • 死锁:多个线程相互等待对方释放资源,导致所有相关线程都无法继续执行。
  • 资源管理:需要合理分配和管理线程使用的资源,例如内存和CPU时间片,以避免资源浪费和性能瓶颈。

同步与异步

同步(Synchronous)和异步(Asynchronous)是计算机科学中描述两种操作执行方式的术语,它们在多线程编程、网络请求、数据库交互等多个领域都有广泛应用。

同步(Synchronous)

同步操作指的是任务按顺序一次完成一个,后一个操作必须等前一个操作完成后才能开始执行。在同步操作中,执行流程是连续的,即一个任务的完成直接导致下一个任务的开始。这意味着在当前任务完成之前,程序不会执行或者转向下一个任务。

同步的特点:

  • 阻塞:同步调用中,调用者需要等待被调用的方法或操作完成后才能继续执行,这期间调用者会被阻塞。
  • 直观:编程模型相对简单,因为代码的执行顺序和书写顺序是一致的,容易理解和预测。
  • 资源利用:可能会导致资源利用不足,特别是在等待I/O(如文件读写、网络请求等)时,CPU可能会处于空闲状态。

异步(Asynchronous)

异步操作允许任务在等待期间不阻塞主程序的运行,可以同时进行多个操作。在异步操作中,可以启动一个任务,并在等待这个任务完成的同时继续执行其他任务。当异步任务完成时,通常通过回调函数、事件、Promise等机制通知调用者。

异步的特点:

  • 非阻塞:调用者发起异步调用后,不需要等待被调用的方法或操作完成,即可继续执行后续代码。
  • 复杂性:编程模型相对复杂,需要处理回调函数、事件监听或者Promise等异步编程的概念,代码的执行顺序不再与书写顺序一致,可能导致“回调地狱”等问题。
  • 资源利用高效:提高了程序的响应性和性能,尤其是在涉及I/O操作时,可以更高效地利用CPU和其他资源,因为主程序在等待异步操作完成的过程中,可以执行其他任务。

选择同步还是异步

  • 如果任务需要顺序执行,且每个操作相对快速,不会造成明显的等待或阻塞,那么同步操作可能更适合。
  • 如果任务包含耗时的I/O操作,或者需要提高程序的响应性和并发性能,那么异步操作将是更好的选择。

Android 为什么要引入异步任务

在Android开发中引入异步任务是为了解决几个核心问题,主要包括保持应用界面的响应性、避免Application Not Responding(ANR)异常以及遵守Android平台的规则。

1. 保持UI的响应性

Android应用的用户界面(UI)操作都是在主线程(也称为UI线程)中执行的。如果在这个线程上执行耗时的任务,如文件读写、网络请求或复杂的计算,会阻塞主线程,导致界面无法更新、响应用户操作,从而影响用户体验。通过使用异步任务,耗时操作可以在后台线程中执行,而不会阻塞UI线程,从而保持应用界面的流畅和响应性。

2. 避免ANR(Application Not Responding)异常

Android系统要求应用程序保持良好的响应性。如果UI线程被阻塞超过5秒钟(对于Broadcast Receiver是10秒),系统就会向用户显示ANR对话框。这通常是因为UI线程正在进行耗时操作而无法处理用户输入或系统事件。通过将耗时操作移到异步任务中,可以避免ANR异常。

3. 遵守Android平台的规则

从Android 3.0(Honeycomb)开始,Android平台不允许在主线程(UI线程)中进行网络操作,如果违反这一规则,应用会抛出NetworkOnMainThreadException异常。这一规定强制开发者将网络请求等耗时操作放在异步任务中处理,以避免阻塞UI线程和提高应用性能。

异步任务的实现方式

虽然AsyncTask是实现异步操作的一种方便方法,但Android开发中有多种方式可以实现异步任务:

  • 使用Thread和Handler:可以在新的线程中执行耗时任务,然后通过Handler在UI线程中更新UI。
  • 使用runOnUiThread(Runnable)方法:如果你需要从非UI线程更新UI,可以使用Activity的runOnUiThread(Runnable)方法,在其中执行UI更新操作。
  • 使用Executor、Future和Callable:这些是Java并发包提供的工具,可以用来执行异步任务并获取结果。
  • 使用协程(Kotlin):对于使用Kotlin开发的Android应用,协程提供了一种更现代、更强大的异步编程模型。

AsyncTask

AsyncTask是Android提供的一个用于简化异步任务执行的抽象类。它允许开发者在后台线程中执行耗时操作,然后在UI线程中更新UI或处理结果,而不会阻塞UI线程。AsyncTask通过泛型参数来指定启动任务执行时输入的参数类型、后台任务执行进度的类型以及后台任务执行完毕后返回的结果类型。以下是这三个泛型参数的详细说明:

AsyncTask<Params, Progress, Result> 参数说明

  • Params:启动任务执行时的输入参数类型。如果你的后台任务需要传入参数,比如一个网络请求的URL,你可以在这里指定这些参数的类型。执行AsyncTask时传入的参数会传递给doInBackground(Params... params)方法。如果不需要输入参数,可以使用Void(注意是大写V的Void)。
  • Progress:后台任务执行时更新进度的类型。如果你希望在后台任务执行过程中更新UI以显示进度(例如下载文件时显示下载百分比),可以在这里指定进度的类型,并在doInBackground方法中调用publishProgress(Progress... values)方法来更新进度。进度会被传递到onProgressUpdate(Progress... values)方法中,该方法运行在UI线程中,允许你更新UI元素。如果不需要更新进度,也可以使用Void。
  • Result:后台任务执行完毕后返回的结果类型。当后台操作完成后,你可能需要返回执行的结果,比如从网络请求获取的数据。这个结果将被传递到onPostExecute(Result result)方法中,该方法也是在UI线程中执行,允许你根据结果更新UI或进行其他操作。如果任务不需要返回结果,同样可以使用Void。

使用AsyncTask的基本步骤

  1. 定义一个类继承AsyncTask:创建一个新的类,继承自AsyncTask,并指定合适的泛型参数。
  2. 重写相关方法:至少需要重写doInBackground(Params... params)方法,在这里实现耗时的后台任务。根据需要,也可以重写onPreExecute()、onProgressUpdate(Progress... values)和onPostExecute(Result result)方法。
  3. 执行AsyncTask:创建AsyncTask子类的实例,并调用execute(Params... params)方法来启动任务。可以传入所需的参数。

AsyncTask 方法与流程

AsyncTask是Android提供的一个用于简化在后台线程上执行任务并在前台更新UI的抽象类。它定义了一系列回调方法,允许开发者在不同阶段对任务进行控制和UI的更新。

onPreExecute():

  • 说明:此方法在执行后台耗时操作前调用,运行在UI线程中。通常用于进行一些准备工作,如显示进度条或初始化界面组件。

doInBackground(Params... params):

  • 说明:在onPreExecute()方法执行完毕后立即执行。该方法运行在后台线程中,主要负责执行耗时的后台处理工作。在这个方法中,可以调用publishProgress(Progress... values)来更新实时的任务进度。
  • 注意:这是唯一一个必须重写的方法,因为它包含了要在后台执行的代码。

onPostExecute(Result result):

  • 说明:在doInBackground(Params... params)执行完毕后,此方法会被UI线程调用。后台任务的运行结果将通过此方法传递到UI线程,并展示给用户。通常用于处理后台操作的结果,如隐藏进度条、显示结果数据等。

onProgressUpdate(Progress... values):

  • 说明:在publishProgress(Progress... values)被调用后,UI线程将调用此方法在界面上展示任务的进度。这个方法是用来更新进度信息的,比如更新进度条。

onCancelled():

  • 说明:当用户取消线程操作时调用,也就是在主线程调用cancel()方法后,会调用此方法。运行在UI线程中,可用于进行取消后的清理操作。

使用AsyncTask的注意事项

  1. 创建实例:AsyncTask的实例必须在UI线程中创建。
  2. 执行任务:execute(Params... params)方法必须在UI线程中调用,用于启动异步任务。
  3. 一次性使用:每个AsyncTask实例只能执行一次,再次执行会抛出异常。
  4. 避免直接调用生命周期方法:不要手动调用onPreExecute()、doInBackground(Params...)、onPostExecute(Result result)、onProgressUpdate(Progress... values)和onCancelled()这些方法,它们由系统根据异步任务的状态自动调用。
  5. 内存泄漏问题:由于AsyncTask是一个匿名内部类,可能会持有Activity的引用,如果任务执行时间较长,可能导致Activity无法被回收,从而引起内存泄漏。建议使用弱引用(WeakReference)来引用Activity或使用其他机制(如ViewModel + LiveData)来避免。

虽然AsyncTask为异步任务提供了方便的实现方式,但由于其存在一些局限性,如容易引起内存泄露、处理并发不够灵活等问题,因此在新的Android开发实践中,AsyncTask已经被标记为过时(deprecated)。

范例

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"tools:context=".MainActivity"><ProgressBarandroid:id="@+id/progressBar"style="?android:attr/progressBarStyleHorizontal"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="50dp" /><TextViewandroid:id="@+id/resultTextView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:layout_below="@id/progressBar"android:layout_marginTop="20dp"android:textSize="18sp"android:textColor="@android:color/black" /></RelativeLayout>
package com.example.myapplication2;import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ProgressBar;
import android.widget.TextView;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private ProgressBar progressBar;private TextView resultTextView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);progressBar = findViewById(R.id.progressBar);resultTextView = findViewById(R.id.resultTextView);MyAsyncTask myAsyncTask = new MyAsyncTask();myAsyncTask.execute();}private class MyAsyncTask extends AsyncTask<Void, Integer, String> {@Overrideprotected void onPreExecute() {super.onPreExecute();// 执行后台耗时操作前做一些初始化工作,显示进度条progressBar.setMax(100);}@Overrideprotected String doInBackground(Void... voids) {// 模拟耗时操作for (int i = 0; i <= 100; i += 10) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}// 更新进度publishProgress(i);}return "任务完成!";}@Overrideprotected void onProgressUpdate(Integer... values) {super.onProgressUpdate(values);// 更新UI界面的进度条progressBar.setProgress(values[0]);}@Overrideprotected void onPostExecute(String result) {super.onPostExecute(result);// 后台任务执行完毕,更新UI界面显示结果resultTextView.setText(result);}}
}

参考文档

  1. Android AsyncTask

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

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

相关文章

【华为OD机试】最多购买宝石数目【C卷|100分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述: 橱窗里有一排宝石,不同的宝石对应不同的价格, 宝石的价格标记为gems[i],0<=i<n, n = gems.length 宝石可同时出售0个或多个,如果同时出售多个,则要求出售的宝石编号连续; 例如…

片上网络(NoC)技术的发展及其给高端FPGA带来的优势

片上网络(NoC)技术的发展及其给高端FPGA带来的优势 1. 概述 在摩尔定律的推动下,集成电路工艺取得了高速发展,单位面积上的晶体管数量不断增加。 片上系统(System-on-Chip,SoC)具有集成度高、功耗低、成本低等优势,已经成为大规模集成电路系统设计的主流方向,解决了…

java017 - Java抽象类

1、概述 一般情况&#xff0c;动物是抽象的&#xff0c;所以不能被new,比如你在Animal类中定义一个成员方法eat,你不能定义具体内容&#xff0c;比如吃鱼或者吃白菜&#xff0c;因为动物是抽象的。 一个没有方法体的方法&#xff0c;应该定义为抽象方法&#xff0c;而类中如果…

I’m stuck!(CCF201312-5)解析(java实现)

代码 package test_201312;import java.util.Scanner;/** 201312-5 试题名称&#xff1a; I’m stuck! 时间限制&#xff1a; 1.0s 内存限制&#xff1a; 256.0MB 问题描述&#xff1a; 问题描述给定一个R行C列的地图&#xff0c;地图的每一个方格可能是#, , -, |, ., S, T七…

Oracle控制文件control file(1)控制文件概述

导读 本文介绍Oracle数据库控制文件control file相关内容 1、控制文件概述 控制文件是数据库中非常重要的一类文件&#xff0c;它记录的当前实例连接的数据库的结构和行为&#xff0c;并维护数据库的一致性。 初始化参数文件中定义了控制文件的位置&#xff1b; 控制文件是很…

抖音短视频小程序发布招聘让招聘更简单!

抖音短视频小程序怎么发布招聘信息呢&#xff1f; 据2023年初统计&#xff0c;全国已有人力资源机构6.3万家&#xff0c;其中在抖音短视频平台发布的人力资源公司有1.9万家以上&#xff0c;全国有近几千家大型企业已经通过抖音平台进行岗位直招。 抖音目前已经成为短视频流量…

2024年最佳硬盘!为台式电脑、NAS等产品量身定做的顶级机械硬盘

机械硬盘&#xff08;HDD&#xff09;可能看起来像是古老的技术&#xff0c;但它们仍然在许多地方提供“足够好”的性能&#xff0c;并且它们很容易以同等的价格提供最多的存储空间。 尽管最好的SSD将为你的操作系统和引导驱动器提供最好的体验&#xff0c;并提供比HDD更好的应…

vite项目修改依赖不更新,清除依赖缓存

有些时候我们会直接修改依赖文件&#xff0c;但修改后没有更新&#xff0c;大多数情况下就是被缓存了 解决方法 1、手动删除node_modules/.vite Vite 会将预构建的依赖缓存到 node_modules/.vite;然后手动删除即可 2、强制vite重新构建依赖 用 --force 命令行选项启动开发服务…

JavaScript this对象

this关键字时是函数运行时自动生成的一个内部对象&#xff0c;只能在函数内部使用&#xff0c;总指向调用它的对象 绑定规则 默认绑定 全局环境中定义函数&#xff0c;内部使用this关键字 var name Jenny; function person() {return this.name; } console.log(person());…

C++项目--高并发内存池

目录 一、项目介绍二、内存池介绍2.1 池化技术2.2 内存池2.3 内存池主要解决的问题2.4 malloc 三、定长内存池的实现3.1 定长内存池概念3.2 内存池管理释放对象3.3 内存池申请对象3.4 定长内存池整体代码3.5 性能对比 四、高并发内存池整体框架设计4.1 该项目解决的问题4.2 整体…

C语言贪吃蛇实现,以及一些有趣的想法(可加速减速)

文章目录 每日一言代码&#xff1a;Snake.hSnake.ctest.c 可以增加游戏趣味性的想法结语 每日一言 结局每隔一段时间就会到来&#xff0c;我经历它&#xff0c;就像飞机穿过云层。 跟着课程敲了一下午&#xff0c;终于写好了~ 用到了一些没用过的函数&#xff0c;总结介绍一下…

【Linux的网络编程】

1、OSI的七层网络模型有哪些&#xff0c;每一层有什么作用&#xff1f; 答&#xff1a;&#xff08;1&#xff09;应用层&#xff1a;负责处理不同应用程序之间的通信&#xff0c;需要满足提供的协议&#xff0c;确保数据发送方和接收方的正确。 &#xff08;2&#xff09;表…

【力扣100】70.爬楼梯 || python中的@cache || 装饰器

添加链接描述 思路&#xff1a; 最后一节楼梯的方式来自倒数第二节和倒数第三节的方法所以使用递归来做&#xff0c;定义递归出口n分别为1,2时候的方法种数&#xff1a;1种和2种类似于斐波那契数列超时了 优化&#xff1a; 5. 因为每次递归都要从n算到n为1和2的时候&#xff0…

安卓Java面试题 1-10

&#x1f525; 1、简述Android的4大组件是哪些&#xff0c;它们的作用&#xff1f;&#x1f525; Android的4大组件 1&#xff1a;Activity&#xff1a;Activity是Android程序与用户交互的窗口&#xff0c;是Android构造块中最基本的一种&#xff0c;它需要为保持各界面的状态…

Pytorch学习 day06(torchvision中的datasets、dataloader)

torchvision的datasets 使用torchvision提供的数据集API&#xff0c;比较方便&#xff0c;如果在pycharm中下载很慢&#xff0c;可以URL链接到迅雷中进行下载&#xff08;有些URL链接在源码里&#xff09;代码如下&#xff1a; import torchvision # 导入 torchvision 库 # …

VM 虚拟机 ubuntu 解决无法连接网络问题

添加网卡法 就是在虚拟机的设置那里多增加一个网卡

如何度量关键成果KR的完成情况?

明确度量指标 首先&#xff0c;需要为每一个关键成果&#xff08;Key Result&#xff09;设定明确的度量指标。这些指标应该是具体、可衡量的&#xff0c;以便能够清晰地反映关键成果的完成情况。例如&#xff0c;如果关键成果是提高网站的用户转化率&#xff0c;那么度量指标…

NOIP 2016普及组初赛试题及解析

NOIP 2016普及组初赛试题及解析 一. 单项选择题 (共20题,每题1.5分,共计30分。每题有且仅有一个正确答案.)。二. 问题求解(共2题,每题5分,共计10分)三. 阅读程序写结果(共4题,每题8分,共计32分)四. 完善程序 (前4空,每空2.5分,后6空,每空3分,共28分)一. 单项选…

论文阅读_解释大模型_语言模型表示空间和时间

英文名称: LANGUAGE MODELS REPRESENT SPACE AND TIME 中文名称: 语言模型表示空间和时间 链接: https://www.science.org/doi/full/10.1126/science.357.6358.1344 https://arxiv.org/abs/2310.02207 作者: Wes Gurnee & Max Tegmark 机构: 麻省理工学院 日期: 2023-10-03…

Linux设备模型(八) - sysfs

一&#xff0c;sysfs目录介绍 sysfs是一个基于内存的虚拟的文件系统&#xff0c;有kernel提供&#xff0c;挂载到/sys目录下&#xff0c;负责以设备树的形式向user space提供直观的设备和驱动信息。 sysfs以不同的视角展示当前系统接入的设备&#xff1a; /sys/block 历史遗…