Android 内存优化(这是一篇完全由chatGPT编写的技术文章)

news/2024/10/25 17:30:31/

0. 导语

chatGPT是最近OpenAI基于GPT-3.5开发的聊天AI,因为功能十分强大,最近非常火爆。我上手简单体验了一番,总体来说达到了惊艳的层次,尤其是能够按照你的描述,写一些代码例子,而且附带通俗易懂的解释。所以我萌生了一个想法,完全使用QA的形式,由我引导让chatGPT写一篇Android的技术文章。过程中,chatGPT偶有犯错的例子,但是你只要直接指出"Error",他就能修正,不过这也提醒我们还是不能完全依赖它。为了避免一些翻译错误,所以本文使用英语提问和解答,用词都很简单,我英语水平很差也能看懂。

1. OnLowMemory

Q: Can you introduce ‘onLowMemory’ in Android?

A: onLowMemory is a callback that is triggered when the system is running low on memory. This callback is generally used to clean up any unnecessary resources that may be taking up memory in an Android app. For example, if an app is using a lot of bitmaps, it could release some of them in the onLowMemory callback to free up memory.

Q:Can you make an example, show ‘onLowMemory’ override by Application class in kotlin, Android?

A:Sure! Here is an example of how you could override the onLowMemory callback in a Application class in Kotlin:


class MyApplication: Application() {override fun onLowMemory() {// Release any unnecessary resources here.super.onLowMemory()}}

In this example, the onLowMemory callback is overridden in the MyApplication class, which extends the Application class. In the onLowMemory method, you can add any code that you want to execute when the system is running low on memory. In this case, the method simply releases any unnecessary resources that may be taking up memory.

Remember to add the MyApplication class to your AndroidManifest.xml file so that it gets used by the system. You can do this by adding the following line inside the <application> element:


<applicationandroid:name=".MyApplication"... >...</application>

This will tell the system to use the MyApplication class as the application class, and the onLowMemory callback will be triggered when the system is running low on memory.

Q:Can you make some example in ‘onLowMemory’ callback, show how to release unnecessary resources?

A:Here is an example of how you could release unnecessary resources in the onLowMemory callback:


class MyApplication: Application() {override fun onLowMemory() {// Release any unnecessary resources here.if (myBitmap != null) {myBitmap.recycle()myBitmap = null}super.onLowMemory()}}

In this example, the onLowMemory callback checks if a bitmap named myBitmap is being used by the app. If it is, the bitmap is recycled and set to null to free up the memory that it was using. This is just one example of how you could release unnecessary resources in the onLowMemory callback. You can add any code that you need to clean up resources in your app here.

Remember to always call the super.onLowMemory() method at the end of the onLowMemory callback to ensure that the system’s default behavior is also executed.

Q:Should I release Glide resource in ‘onLowMemory’ callback?

A:It is generally not necessary to release Glide resources in the onLowMemory callback. Glide already has its own system for managing memory and will automatically release unused resources when the system is running low on memory.

However, if you are using Glide in a way that is not recommended, or if you are using a lot of large images in your app, it may be necessary to release Glide resources in the onLowMemory callback. In this case, you can use the Glide.with(context).onLowMemory() method to tell Glide to release any unused resources.

Here is an example of how you could use the onLowMemory method in Glide:


class MyApplication: Application() {override fun onLowMemory() {// Release Glide resources here.Glide.with(this).onLowMemory()super.onLowMemory()}}

In this example, the onLowMemory callback is overridden in the MyApplication class, which extends the Application class. In the onLowMemory method, the onLowMemory method of Glide is called to release any unused resources. This will help to reduce the amount of memory that Glide is using in your app.

Remember that calling the onLowMemory method in Glide is only necessary in certain cases. In most cases, Glide will automatically manage its own memory usage and there is no need to release its resources in the onLowMemory callback.

2. MemoryLeak

**Q:Can you introduce what is MemoryLeak? Why some languages like Java and Kotlin, which garbage collector can automatically release memory, but it still possible to create memory leak? **

A:A memory leak is a type of software bug where a program continues to hold onto memory that it is no longer using. This can cause the program to use an excessive amount of memory, which can lead to poor performance or even crashes.

Memory leaks are particularly common in languages like C and C++, where memory management is the responsibility of the programmer. In these languages, it is easy to accidentally create a memory leak by not properly releasing memory when it is no longer needed.

However, memory leaks can also occur in other languages, such as Java and Kotlin, that have a garbage collector. In these languages, the garbage collector is responsible for automatically releasing memory that is no longer in use. However, it is still possible to create memory leaks if objects are not properly released.

For example, if an object is referenced by another object, it may not be eligible for garbage collection even if it is no longer needed. In this case, the object will continue to take up memory, even though it is no longer being used by the program. This is an example of a memory leak.

Memory leaks can be difficult to diagnose and fix, but they are important to address because they can lead to poor app performance and instability. To prevent memory leaks, it is important to carefully manage memory usage in your app and release any unnecessary objects when they are no longer needed.

Q:Can you make an example, show MemoryLeak in Kotlin, Android?

A:Sure! Here is an example of a simple memory leak in Kotlin:


class MainActivity : Activity() {// This is a potential source of memory leak because the Runnable is holding// a reference to the MainActivity, which is a non-static inner class of// MainActivity. This means that as long as the Runnable is alive, it will// hold a reference to the MainActivity, preventing it from being garbage// collected even if the user navigates away from the MainActivity.private val mLeakyRunnable = Runnable {// ...}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// ...// Here, we are posting the Runnable to a Handler, which will keep it// alive until it is executed or removed from the message queue.val handler = Handler()handler.post(mLeakyRunnable)}}

In this example, the MainActivity class is creating a Runnable that is held by a Handler and posted to a message queue. This is a potential source of memory leak because the Runnable is holding a reference to the MainActivity, which is a non-static inner class of MainActivity. This means that as long as the Runnable is alive, it will hold a reference to the MainActivity, preventing it from being garbage collected even if the user navigates away from the MainActivity. To avoid this, we should either make the Runnable a static inner class of MainActivity, or use a weak reference to the MainActivity in the Runnable.

Q:Can you show both approach to avoid memory leak?

A: Sure, here are two approaches to avoid the memory leak in the example I provided earlier:

  1. Make the Runnable a static inner class of MainActivity:

class MainActivity : Activity() {private val mLeakyRunnable = LeakyRunnable()// The Runnable is now a static inner class of MainActivity, which means// that it no longer holds a reference to the MainActivity. This means// that the MainActivity can be garbage collected even if the Runnable// is still alive.private class LeakyRunnable : Runnable {override fun run() {// ...}}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// ...val handler = Handler()handler.post(mLeakyRunnable)}}

2.Use a weak reference to the MainActivity in the Runnable:


class MainActivity : Activity() {// This is a potential source of memory leak because the Runnable is holding// a reference to the MainActivity, which is a non-static inner class of// MainActivity. This means that as long as the Runnable is alive, it will// hold a reference to the MainActivity, preventing it from being garbage// collected even if the user navigates away from the MainActivity.private val mLeakyRunnable = Runnable {// ...}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// ...// Here, we are using a weak reference to the MainActivity in the// Runnable. This means that the Runnable will not prevent the// MainActivity from being garbage collected if the user navigates// away from the MainActivity.val weakReference = WeakReference(this)val runnable = Runnable {val mainActivity = weakReference.get()if (mainActivity != null) {// ...}}val handler = Handler()handler.post(runnable)}}

In the second approach, we are using a WeakReference to the MainActivity in the Runnable. This means that the Runnable will not prevent the MainActivity from being garbage collected if the user navigates away from the MainActivity. This avoids the potential memory leak.

Q:Can you make an example, show memory leak when using coroutine in Kotlin, Android?

A:Sure, here is an example of a potential memory leak when using coroutines in Kotlin for an Android app:


class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// ...// Here, we are launching a coroutine in the GlobalScope. This means// that the coroutine will not be cancelled when the MainActivity is// destroyed, which can potentially lead to a memory leak if the// coroutine is holding a reference to the MainActivity.GlobalScope.launch {// ...}}}

In this example, the MainActivity is launching a coroutine in the GlobalScope. This means that the coroutine will not be cancelled when the MainActivity is destroyed, which can potentially lead to a memory leak if the coroutine is holding a reference to the MainActivity. To avoid this, we should either use a CoroutineScope that is tied to the lifecycle of the MainActivity and cancel it in the onDestroy() method of the MainActivity, or use the viewModelScope provided by the AndroidViewModel class to launch our coroutines.

Q:Can you make an example, show ‘viewModelScope’ avoid memory leak in Kotlin, Android?

A:Sure, here is an example of using viewModelScope to avoid a potential memory leak when using coroutines in Kotlin for an Android app:


class MainActivity : AppCompatActivity() {private val viewModel = MainViewModel(this.application)override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// ...// Here, we are calling a method on the ViewModel that launches a// coroutine using the viewModelScope provided by the AndroidViewModel// class. This will automatically cancel the coroutine when the// ViewModel is cleared, which occurs when the MainActivity is// destroyed.viewModel.doWork()}}class MainViewModel(application: Application) : AndroidViewModel(application) {// Here, we are using the viewModelScope provided by the AndroidViewModel// class to launch our coroutine. This will automatically cancel the// coroutine when the ViewModel is cleared, which occurs when the// MainActivity is destroyed.fun doWork() {viewModelScope.launch {// ...}}}

In this example, we are using the viewModelScope provided by the AndroidViewModel class to launch our coroutine. This will automatically cancel the coroutine when the ViewModel is cleared, which occurs when the Activity is destroyed, avoiding any potential memory leaks. This is a safer and more convenient approach than using MainScope or GlobalScope and manually cancelling the coroutines when the Activity is destroyed.

Q:Can you make an example, show RxJava memory leak in Kotlin, Android?

A:Sure, here is an example of a potential memory leak when using RxJava in Kotlin for an Android app:


class MainActivity : AppCompatActivity() {// This is a potential source of memory leak because the Observable is// holding a reference to the MainActivity, which is a non-static inner// class of MainActivity. This means that as long as the Observable is// alive, it will hold a reference to the MainActivity, preventing it from// being garbage collected even if the user navigates away from the// MainActivity.private val observable = Observable.create<Int> { emitter ->emitter.onNext(1)emitter.onNext(2)emitter.onNext(3)emitter.onComplete()}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// ...// Here, we are subscribing to the Observable. This will cause the// Observable to hold a reference to the MainActivity, which can// prevent it from being garbage collected even if the user navigates// away from the MainActivity.observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe { value ->// ...}}}

In this example, the MainActivity is creating an Observable that is holding a reference to the MainActivity, which is a non-static inner class of MainActivity. This means that as long as the Observable is alive, it will hold a reference to the MainActivity, preventing it from being garbage collected even if the user navigates away from the MainActivity. To avoid this, we should either make the Observable a static inner class of MainActivity, or use a weak reference to the MainActivity in the Observable.

Q:Can you make an example, show how to use ‘lifecycle’ to avoid memory leak when using RxJava, in Kotlin?

A:Sure, here is an example of using the lifecycle API to avoid a potential memory leak when using RxJava in Kotlin for an Android app:


class MainActivity : AppCompatActivity() {private val observable = Observable.create<Int> { emitter ->emitter.onNext(1)emitter.onNext(2)emitter.onNext(3)emitter.onComplete()}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// ...// Here, we are subscribing to the Observable using the lifecycle API.// This will automatically dispose the subscription when the// MainActivity is destroyed, avoiding any potential memory leaks.observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe { value ->// ...}.disposeBy(this)}}

In this example, we are using the lifecycle API to subscribe to the Observable. This will automatically dispose the subscription when the MainActivity is destroyed, avoiding any potential memory leaks. This is a safer and more convenient approach than using a weak reference or a static inner class, as I described in my previous response.

3. Image Manager

Q:Can you make an example, show how to create a RGB565 imageView instead of RGB888 imageView by using Glide, in Kotlin, Android

A:Sure, here is an example of using Glide to create an ImageView that uses the RGB565 pixel format instead of the default RGB888 pixel format in an Android app written in Kotlin:


class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// ...// Here, we are creating an ImageView that uses the RGB565 pixel// format instead of the default RGB888 pixel format.val imageView = ImageView(this)Glide.with(this).asBitmap().load(R.drawable.my_image).format(DecodeFormat.PREFER_RGB_565).into(imageView)}}

In this example, we are using Glide to load an image and display it in an ImageView. We are specifying that we want to use the RGB565 pixel format by calling the format() method and passing in DecodeFormat.PREFER_RGB_565 as the argument. This will cause Glide to create an ImageView that uses the RGB565 pixel format instead of the default RGB888 pixel format.

Q:Can you make an example, show how to use Glide scaling and resizing techniques to reduce this size of image?

A:Sure, here is an example of using Glide’s scaling and resizing techniques to reduce the size of an image in an Android app written in Kotlin:


class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// ...// Here, we are using Glide to load an image and apply a scaling// transformation to it. The scale factor we are using here will// reduce the size of the image by half, which will in turn reduce// the amount of memory required to store the image.val imageView = ImageView(this)Glide.with(this).asBitmap().load(R.drawable.my_image).override(100, 100).into(imageView)}}

In this example, we are using Glide to load an image and apply a scaling transformation to it using the override() method. This method takes the desired width and height of the image as arguments, and will cause Glide to scale the image to those dimensions. In this case, we are specifying that we want the image to be 100 pixels wide and 100 pixels tall, which will reduce the size of the image by half. This will reduce the amount of memory required to store the image and improve the performance of your app.

Alternatively, you can use the centerCrop() or fitCenter() methods to apply different resizing techniques to the image. These methods will automatically resize the image to fit within the specified dimensions while maintaining the aspect ratio of the image, so the resulting image may not be exactly the size you specified. For example:


class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// ...// Here, we are using Glide to load an image and apply a fitCenter// transformation to it. This will cause Glide to resize the image// to fit within the specified dimensions while maintaining the// aspect ratio of the image.val imageView = ImageView(this)Glide.with(this).asBitmap().load(R.drawable.my_image).fitCenter().into(imageView)}}

You can experiment with different scaling and resizing techniques to find the one that works best for your images and your app.

Q:Can you make an example, show how to limit memory size in 100MB when using Glide, In Kotlin, Android?

A:Sure, here is an example of using Glide to limit the memory size of an image in an Android app written in Kotlin:


class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// ...// Here, we are using Glide to load an image and limit the memory// size of the image to 100MB. If the image exceeds this size,// Glide will automatically scale it down to fit within the// specified limit.val imageView = ImageView(this)Glide.with(this).asBitmap().load(R.drawable.my_image).setMemoryCache(LruResourceCache(100 * 1024 * 1024)).into(imageView)}}

In this example, we are using Glide to load an image and limit the memory size of the image to 100MB using the setMemoryCache() method. This method takes a MemoryCache object as an argument, and we are using the LruResourceCache class to create a memory cache with a size limit of 100MB. If the image exceeds this size, Glide will automatically scale it down to fit within the specified limit. This can help to improve the performance and reduce the memory footprint of your app.

You can adjust the size limit of the memory cache to suit your specific needs. For example, if you want to limit the memory size to 50MB, you can use the following code:


Glide.with(this).asBitmap().load(R.drawable.my_image).setMemoryCache(LruResourceCache(50 * 1024 * 1024)).into(imageView)

Alternatively, you can use a different MemoryCache implementation, such as the LimitedAgeMemoryCache class, to limit the age of the entries in the memory cache instead of the size. This can be useful if you want to avoid caching very large images that may not be used often. For example:


Glide.with(this).asBitmap().load(R.drawable.my_image).setMemoryCache(LimitedAgeMemoryCache(TimeUnit.MINUTES.toMillis(5))).into(imageView)

Q:Can you set this limit to all Images?

A:Yes, you can set the memory size limit for all images loaded by Glide by configuring the default MemoryCache implementation used by Glide. This can be done using the GlideBuilder class, which allows you to customize the default settings for Glide.

Here is an example of using the GlideBuilder class to set the memory size limit for all images loaded by Glide:


class MyApplication : Application() {override fun onCreate() {super.onCreate()// ...// Here, we are using the GlideBuilder class to set the memory size// limit for all images loaded by Glide to 100MB. If an image// exceeds this size, Glide will automatically scale it down to// fit within the specified limit.Glide.init(Glide.Builder(this).setMemoryCache(LruResourceCache(100 * 1024 * 1024)))}}

In this example, we are using the GlideBuilder class to create a new instance of Glide with custom settings. We are calling the setMemoryCache() method to set the memory size limit for all images loaded by Glide to 100MB using the LruResourceCache class. This will cause Glide to automatically scale down any images that exceed this size limit to fit within the specified limit.

Once you have configured the default MemoryCache implementation, you can use Glide as you normally would without having to specify the memory size limit for each image. For example:


class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// ...// Here, we are using Glide to load an image without specifying// the memory size limit. The default memory size limit that we// set using the GlideBuilder class will be used instead.val imageView = ImageView(this)Glide.with(this).asBitmap().load(R.drawable.my_image).into(imageView)}}

In this example, we are using Glide to load an image without specifying the memory size limit. Because we have configured the default MemoryCache implementation using the GlideBuilder class, the memory size limit that we set will be used automatically for all images loaded by Glide. This can make it easier to manage the memory usage of your app and ensure that it performs well.

Q:How to make callback if the image is out of limit?

A:To make a callback if an image is out of the memory size limit when using Glide, you can use the RequestListener interface and implement the onLoadFailed() method. This method will be called whenever an error occurs while loading an image, including when the image exceeds the memory size limit.

Here is an example of using the RequestListener interface to make a callback if an image is out of the memory size limit when using Glide:


class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// ...// Here, we are using Glide to load an image and specifying a// RequestListener that will be called if the image is out of the// memory size limit.val imageView = ImageView(this)Glide.with(this).asBitmap().load(R.drawable.my_image).listener(object : RequestListener<Bitmap> {override fun onLoadFailed(e: GlideException?,model: Any?,target: Target<Bitmap>?,isFirstResource: Boolean): Boolean {// This method will be called if the image is out of// the memory size limit. You can use this method to// make a callback or perform some other action.return false}override fun onResourceReady(resource: Bitmap?,model: Any?,target: Target<Bitmap>?,dataSource: DataSource?,isFirstResource: Boolean): Boolean {// This method will be called if the image is loaded// successfully. You can ignore this method if you are// only interested in handling errors.return false}}).into(imageView)}}

In this example, we are using Glide to load an image and specifying a RequestListener that will be called if the image is out of the memory size limit. The onLoadFailed() method of the RequestListener will be called if the image is out of the memory size limit, and you can use this method to make a callback or perform some other action. This can be useful for handling errors and ensuring that your app continues to function properly even if an image exceeds the memory size limit.

Q: Can you set this callback for all image loader?

A: Yes, you can set the callback for all image loads using Glide by configuring the default RequestListener implementation used by Glide. This can be done using the GlideBuilder class, which allows you to customize the default settings for Glide.

Here is an example of using the GlideBuilder class to set the callback for all image loads using Glide:


class MyApplication : Application() {override fun onCreate() {super.onCreate()// ...// Here, we are using the GlideBuilder class to set the callback// for all image loads using Glide. The callback will be called// if the image is out of the memory size limit.Glide.init(Glide.Builder(this).setDefaultRequestListeners(object : RequestListener<Any> {override fun onLoadFailed(e: GlideException?,model: Any?,target: Target<Any>?,isFirstResource: Boolean): Boolean {// This method will be called if the image is out// of the memory size limit. You can use this method// to make a callback or perform some other action.return false}override fun onResourceReady(resource: Any?,model: Any?,target: Target<Any>?,dataSource: DataSource?,isFirstResource: Boolean): Boolean {// This method will be called if the image is// loaded successfully. You can ignore this method// if you are only interested in handling errors.return false}}))}}

In this example, we are using the GlideBuilder class to create a new instance of Glide with custom settings. We are calling the setDefaultRequestListeners() method to set the default RequestListener implementation for all image loads using Glide. This RequestListener will be called if the image is out of the memory size limit, and you can use this method to make a callback or perform some other action.

Once you have configured the default RequestListener implementation, you can use Glide as you normally would without having to specify a RequestListener for each image load. For example:


class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// ...// Here, we are using Glide to load an image without specifying// the RequestListener. The default RequestListener that we set// using the GlideBuilder class will be used instead.val imageView = ImageView(this)Glide.with(this).asBitmap().load(R.drawable.my_image).into(imageView)}}

In this example, we are using Glide to load an image without specifying a RequestListener. Because we have configured the default RequestListener implementation using the GlideBuilder class, the callback that we set will be used automatically for all image loads using Glide. This can make it easier to handle errors and ensure that your app continues to function properly even if an image exceeds the memory size limit.


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

相关文章

chatGPT批量生成器产出的文章能不能用做网站SEO优化

随着人工智能技术的迅猛发展&#xff0c;ChatGPT成为了内容创作者和营销人员的宝贵助手。那么&#xff0c;问题来了&#xff0c;这些由ChatGPT批量生成的文章能否成为网站SEO优化的利器呢&#xff1f;本文将深入探讨这个问题&#xff0c;并为你提供一些实用的技巧&#xff0c;帮…

API漏洞检测研究

xray API漏洞检测_青霄的博客-CSDN博客 Swagger ui接口自动化批量漏洞测试_swgeer-ui 漏洞_山山而川的博客-CSDN博客 什么是 API 安全测试以及它是如何工作的&#xff1f; | Synopsys API 安全测试针对应用程序编程接口 (API) &#xff0c;就其安全性、正确性和可靠性进行测试&…

[RK3568] AMP架构

Rockchip 平台异构多系统 AMP &#xff08;非对称多核架构&#xff09;的开发软件包&#xff0c;支持 Linux(Kernel) 、 Standalone(Hal)、 RTOS(RT-Thread) 组合 AMP 构建形式。 Standalone(Hal) HAL&#xff1a;Hardware Abstraction Layer&#xff0c;硬件抽象层。 硬件抽…

putty 快速登录服务器的方法

Session 选项卡中填写 Host Name, Port, Save Sessions, 假定名称为 tiktok 右键 putty 快捷方式&#xff0c;属性 > 快捷方式 > 目标&#xff0c;加入下面的参数 -load "tiktok" -l "root" -pw "密码"Mac 连接就直接在控制台输入以下命…

记录在编写ChatGPT爬虫网页时的问题

在编写好获取星球问题的爬虫后通过topic_id来找到问题的回答 获取没问题&#xff0c;是正常获取数据的。 但是在回答问题的时候应该直接导入topic_id而不要先在网页上回答了再去测试。不然会获取不到数据而导致错误代码1004

python 爬虫爱好者必须掌握的知识点“ 协程爬虫”,看一下如何用 gevent 采集女生用头像

本篇博客是 python 爬虫 120 例中,基础知识补充篇,内容将围绕 python 协程进行。 在开始协程相关知识前,先补充一下预备概念。 在 python 爬虫的学习过程中,经常要区分两个概念,一个叫做 I/O 密集型任务,另一个叫做 计算密集型任务。 以上两种任务,都有 2 个前提,一是…

利用chatgpt帮我写爬虫代码

首先我这里需要先赋予它一个身份&#xff0c;以便他更好的理解我们的话 接下来就可以让他帮我们写代码了 import requests from bs4 import BeautifulSoup# 请求头部信息&#xff0c;模拟浏览器访问 headers {user-agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/5…

怎样构建抖音壁纸表情包小程序?

第一&#xff0c;最新版本的图片小程序&#xff0c;壁纸表情头像游戏教程&#xff0c;教你跟上抖音小程序的步伐 我们都很熟悉取图(抖音演示:云云取图)。 传统的方法是搜索密码&#xff0c;然后下载和观看广告。这样&#xff0c;在瞬息万变的网络中&#xff0c;竞争力是有限的。…