[Android]常见的数据传递方式

news/2024/2/21 3:28:19

Demo:https://github.com/Gamin-fzym/DataTransferDemo

1.Intent

发送页面 A 到页面 B 的 Intent 时,可以通过 Intent 的 putExtra() 方法将数据附加到 Intent 上。

在页面 B 中,通过 Intent 的 getXXXExtra() 方法获取传递的数据。

1).在A页面发送 Intent

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import com.example.datatransferdemo.databinding.ActivityMainBinding
import com.example.datatransferdemo.pageb.PageB1class MainActivity : AppCompatActivity() {private lateinit var binding: ActivityMainBinding// 获取返回结果,在Activity或Fragment中定义private val someActivityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->if (result.resultCode == Activity.RESULT_OK) {// 执行成功后的操作val intent: Intent? = result.datawhen (intent?.tag) {"PageB1" -> {var resultValue = intent?.getStringExtra("result_key")}"PageB2" -> {val bundle = intent?.extras}}}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)// 1.Intentbinding.button1.setOnClickListener {val intent = Intent(this, PageB1::class.java)intent.putExtra("key", "传递字符串") // 可选:添加要传递的数据// 启动目标 Activity//startActivity(intent)// 如果希望在目标 Activity 中获取返回结果,使用ActivityResultLauncher来启动someActivityResultLauncher.launch(intent);}}}

2).在B页面接收数据

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import com.example.datatransferdemo.Rclass PageB1 : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_page_b1)// 获取传递过来的值val value = intent.getStringExtra("key")// 离开回传数据val but = findViewById<Button>(R.id.button)but.setOnClickListener {val returnIntent = Intent()returnIntent.tag = "PageB1"returnIntent.putExtra("result_key", "返回字符串")setResult(RESULT_OK, returnIntent)finish() // 结束当前Activity, 不一定要立即结束。}}
}

3).拓展Intent用来区分回传数据

使用扩展函数为 Intent 添加一个自定义的 tag属性

import android.content.Intentvar Intent.tag: String?get() = getStringExtra("tag")set(value) {putExtra("tag", value)}

2.Bundle

类似于 Intent,可以使用 Bundle 在页面间传递数据。

在发送页面 A 到页面 B 的过程中,将数据放入 Bundle 对象中。

在接收页面 B 中,从 Intent 中获取 Bundle 对象,并从 Bundle 中提取数据。

1).在A页面发送 Bundle

val bundle = Bundle()
bundle.putInt("id",123)
bundle.putBoolean("status",true)
bundle.putString("content", "传递字符串")
val intent = Intent(this, PageB2::class.java)
intent.putExtras(bundle)
// 启动目标 Activity
//startActivity(intent)
// 获取返回结果启动
someActivityResultLauncher.launch(intent);

2).在B页面接收数据

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.example.datatransferdemo.R
import com.example.datatransferdemo.tagclass PageB2 : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_page_b2)// 获取传递过来的值val bundle = intent.extrasval receivedID = bundle?.getInt("id") // 根据传递的数据类型使用对应的 getXXX() 方法val receivedStatus = bundle?.getBoolean("status")val receivedContent = bundle?.getString("content")// 离开回传数据val returnBundle = Bundle()returnBundle.putInt("id",123)returnBundle.putBoolean("status",true)returnBundle.putString("content", "传递字符串")val returnIntent = Intent()returnIntent.tag = "PageB2"returnIntent.putExtras(returnBundle)setResult(RESULT_OK, returnIntent)}
}

3.静态变量

在一个类中定义一个静态变量,其他页面可以直接访问该静态变量来传递数据。

适用于全局范围内需要传递数据的情况,但不适用于临时或有生命周期的数据传递。

1).定义静态变量

object StaticDataHolder {var sharedData = mapOf<String,String>()
}

2).在A页面设置数据

 StaticDataHolder.sharedData = mapOf<String,String>("id" to "1234", "status" to "1", "content" to "传递字符串")

3).在B页面获取数据

val receivedData = StaticDataHolder.sharedData

4.SharedPreferences

使用 SharedPreferences 可以存储和读取键值对数据,并在不同页面间共享数据。

适用于需要长期存储和共享数据的情况。

1).在A页面设置数据

val sharedPref = getSharedPreferences("my_prefs", Context.MODE_PRIVATE)
val editor = sharedPref.edit()
editor.putString("key", data) // data 是要传递的数据
editor.apply()

2).在B页面获取数据

val sharedPref = getSharedPreferences("my_prefs", Context.MODE_PRIVATE)
val receivedData = sharedPref.getString("key", "") // 根据传递的数据类型使用对应的 getXXX() 方法

5.接口回调(Interface Callback)

定义一个接口,在页面 A 中实现该接口,并将实现类的实例传递给页面 B。

页面 B 可以调用接口的方法来传递数据给页面 A。

适用于页面间有交互和回调需求的情况。

1).定义接口

interface DataCallback {fun onDataReceived(data: String)
}

2).在页面 A 中实现接口

class PageA : AppCompatActivity(), DataCallback {// 静态的DataCallback实例companion object {var callbackInstance: DataCallback? = null}override fun onDestroy() {super.onDestroy()callbackInstance = null // 防止内存泄漏}        override fun onDataReceived(data: String) {// 处理接收到的数据}// 在需要传递数据的地方将实现类的实例传递给页面 BcallbackInstance = this;val intent = Intent(this, PageB5::class.java)startActivity(intent)
}

3).在页面 B 中使用接口传递数据

  // 调用DataCallback的方法if (MainActivity.callbackInstance != null) {MainActivity.callbackInstance?.onDataReceived("传递的数据")}

6.EventBus

使用 EventBus 库来进行页面间的事件传递和数据通信。

页面 A 发布一个事件,页面 B 订阅该事件并接收数据。

适用于解耦和简化页面间通信的情况。

1).添加 EventBus 到你的项目依赖中

dependencies {implementation 'org.greenrobot:eventbus:3.3.1'
}

2).创建一个事件类

这个类的作用是在组件之间传递数据

class MessageEvent(val message: String)

3).注册和注销EventBus

在您想要接收事件的组件(如Activity或Fragment)中,注册和注销EventBus。

override fun onStart() {super.onStart()EventBus.getDefault().register(this)
}override fun onStop() {super.onStop()EventBus.getDefault().unregister(this)
}

4).监听事件

在相同的组件中,添加一个方法来监听事件,这个方法需要用@Subscribe注解。

@Subscribe(threadMode = ThreadMode.MAIN)
public fun onMessageEvent(event: MessageEvent) {// 处理事件val data = event.message// ...处理数据
}

5).发布事件

在需要发送数据的地方,发布一个事件实例。

EventBus.getDefault().post(MessageEvent("Hello, EventBus!"))

6).示例

接收方

class ReceiverActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_receiver)}override fun onStart() {super.onStart()EventBus.getDefault().register(this)}override fun onStop() {super.onStop()EventBus.getDefault().unregister(this)}@Subscribe(threadMode = ThreadMode.MAIN)public fun onMessageEvent(event: MessageEvent) {// 这里处理接收到的事件Toast.makeText(this, event.message, Toast.LENGTH_SHORT).show()}
}

发送方

class SenderActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_sender)// 假设有一个按钮用于发送事件val sendButton: Button = findViewById(R.id.sendButton)sendButton.setOnClickListener {// 当按钮被点击时,发布事件EventBus.getDefault().post(MessageEvent("Hello from SenderActivity!"))}}
}

7.Application 类

1).创建自定义Application类

创建一个新的Kotlin类,继承自Application类,并在该类中定义你想要传递的数据。

class MyApp : Application() {var globalData: String? = null// 你可以在这里定义更多的变量或方法
}

2).在AndroidManifest.xml中声明

在AndroidManifest.xml文件中的<application>标签内,使用android:name属性来指定你的自定义Application类。

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

3).在Activity或其他组件中使用

在任何Activity或其他组件中,你可以通过调用getApplication()方法来获取自定义Application类的实例,并访问其中定义的数据。

class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val app = application as MyAppapp.globalData = "Some data"}
}

注意事项

  • 使用Application传递数据时,要注意生命周期,因为当Android系统需要为其他应用释放内存时,它可能会杀死后台进程,这会导致Application对象被重建,数据可能会丢失。

  • 这种方法适合传递少量的、全局需要的数据。如果数据量较大或者需要持久化存储,应该考虑使用数据库、SharedPreferences或其他存储机制。

  • 为了避免内存泄漏,不要在Application类中持有Activity、View或其他上下文相关的引用。

通过这种方式,你可以在不同的组件间共享数据,但要确保对共享数据的访问是线程安全的。

8.Parcelable

Parcelable和Serializable是两种常用的数据传递方式。Parcelable是Android特有的接口,性能比Serializable好,但实现稍微复杂一些。Serializable是Java提供的接口,实现简单,但性能较差。

实现 Parcelable 接口,使对象能够在页面间进行序列化和反序列化传递。

适用于需要传递自定义对象的情况。

1).创建一个数据类,并实现Parcelable接口。

import android.os.Parcelable
import kotlinx.parcelize.Parcelize@Parcelize
data class User(val name: String, val age: Int) : Parcelable

从Kotlin 1.1.4开始,可以使用@Parcelize注解来自动实现Parcelable接口,前提是在项目的build.gradle文件中启用了kotlin-parcelize插件。

plugins {// 其它插件...id("org.jetbrains.kotlin.plugin.parcelize") 
}

2).在启动新Activity时,将Parcelable对象放入Intent。

val intent = Intent(this, SecondActivity::class.java).apply {val user = User("John Doe", 30)putExtra("USER_KEY", user)
}
startActivity(intent)

3).在接收Activity中,从Intent中取出Parcelable对象。

class SecondActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_second)val user = intent.getParcelableExtra<User>("USER_KEY")user?.let {// 使用user对象}}
}

注意: 当使用Serializable时,所有序列化的对象中的子对象也必须实现Serializable接口。而Parcelable则需要每个子对象都要实现Parcelable接口。

建议在Android中优先使用Parcelable,因为它比Serializable更高效。

9.Serializable

创建一个实现 Serializable 接口的数据类。

在发送页面中创建数据对象,并将其放入 Intent 中。

在接收页面中从 Intent 中获取传递的 Serializable 对象。

1).创建一个数据类,并实现Serializable接口。

import java.io.Serializabledata class User(val name: String, val age: Int) : Serializable

2).在启动新Activity时,将Serializable对象放入Intent。

val intent = Intent(this, SecondActivity::class.java).apply {val user = User("John Doe", 30)putExtra("USER_KEY", user)
}
startActivity(intent)

3).在接收Activity中,从Intent中取出Serializable对象。

class SecondActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_second)val user = intent.getSerializableExtra("USER_KEY") as? Useruser?.let {// 使用user对象}}
}

10.数据库(Database)

使用数据库存储数据,并在不同页面间读取和写入数据。

可以使用 SQLite、Room 等数据库框架进行数据的持久化和共享。

适用于需要长期存储和大量数据共享的情况。

1).添加依赖

在项目的build.gradle文件中,添加Room数据库的依赖。

plugins {id("kotlin-kapt")
}android {...defaultConfig {...kapt {arguments {arg("room.schemaLocation", "$projectDir/schemas")}}}compileOptions {sourceCompatibility = JavaVersion.VERSION_17targetCompatibility = JavaVersion.VERSION_17}kotlinOptions {jvmTarget = "17"}...
}dependencies {implementation("androidx.room:room-runtime:2.5.0")//annotationProcessor("androidx.room:room-compiler:2.5.0")// For Kotlin use kapt instead of annotationProcessorkapt("androidx.room:room-compiler:2.5.0")// optional - Kotlin Extensions and Coroutines support for Roomimplementation("androidx.room:room-ktx:2.5.0")
}

2).定义数据模型

创建一个数据类,并使用@Entity注解标记,表示这是一个数据库表。

import androidx.room.Entity
import androidx.room.PrimaryKey@Entity
data class User(@PrimaryKey val id: Int,val name: String,val age: Int
)

3).创建DAO(数据访问对象)

定义一个接口,使用@Dao注解标记,里面包含访问数据库的方法。

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query@Dao
interface UserDao {@Insertsuspend fun insertUser(user: User): Long@Query("SELECT * FROM user WHERE id = :id")suspend fun getUserById(id: Int): User?
}

4).创建数据库实例

创建一个抽象类,继承自RoomDatabase,并使用@Database注解。

import androidx.room.Database
import androidx.room.RoomDatabase@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {abstract fun userDao(): UserDao
}

5).使用数据库

在您的Activity或Fragment中,获取数据库实例并执行数据库操作。

val db = Room.databaseBuilder(applicationContext,AppDatabase::class.java, "database-name"
).build()val userDao = db.userDao()// 插入用户
GlobalScope.launch {userDao.insertUser(User(1, "John Doe", 30))// 测试时每次修改一下ID,不然存在相同ID会报错
}// 查询用户
GlobalScope.launch {val user = userDao.getUserById(1)// 使用user对象
}

注意:

  • 上述代码中使用了Kotlin协程来处理异步数据库操作。

  • Room.databaseBuilder()需要一个Context对象,通常您会在Activity或Application中调用它。

  • 数据库操作(如插入和查询)不应在主线程上执行,因为它们可能会阻塞UI,所以应该在协程或其他异步机制中运行。

  • GlobalScope的使用在真实的应用程序中并不推荐,因为它的生命周期是整个应用程序,您应该使用具有更短生命周期的作用域,如lifecycleScope或viewModelScope。

11.文件(File)

将数据存储到文件中,在不同页面间通过读写文件来传递数据。

可以使用内部存储或外部存储来创建和访问文件。

适用于大量数据或需要持久化存储的情况。

1).定义一个帮助类或者函数来处理文件的读写操作

以下是一个简单的例子:

import android.content.Context
import java.io.*class FileHelper(private val context: Context) {fun writeToFile(fileName: String, data: String) {context.openFileOutput(fileName, Context.MODE_PRIVATE).use { outputStream ->outputStream.write(data.toByteArray())}}fun readFromFile(fileName: String): String {return context.openFileInput(fileName).bufferedReader().useLines { lines ->lines.fold("") { some, text ->"$some\n$text"}}}
}

2).在您的Activity或Fragment中,您可以使用这个帮助类来存储数据到文件。

class SomeActivity : AppCompatActivity() {private lateinit var fileHelper: FileHelperoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_some)fileHelper = FileHelper(this)// 保存数据到文件val dataToSave = "Some data to be shared"fileHelper.writeToFile("shared_data.txt", dataToSave)}private fun loadData() {// 从文件中读取数据val data = fileHelper.readFromFile("shared_data.txt")// 使用读取的数据// ...}
}

3).在另一个页面,您可以使用相同的FileHelper实例来读取之前写入的文件。

class AnotherActivity : AppCompatActivity() {private lateinit var fileHelper: FileHelperoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_another)fileHelper = FileHelper(this)// 读取数据val sharedData = fileHelper.readFromFile("shared_data.txt")// 使用数据// ...}
}

确保在使用文件进行数据传递时考虑到线程安全和性能问题。对于大量数据或频繁的读写操作,可能需要考虑使用其他数据传递方法,例如数据库或SharedPreferences。此外,对于敏感数据,请确保适当加密,以保护用户数据安全。

12. 网络请求(Network Request)

使用网络请求来传递数据,可以通过 HTTP 请求或其他网络协议进行数据交换。

发送方将数据通过网络发送给接收方,接收方通过解析网络响应来获取数据。

适用于远程数据交换或与服务器进行通信的情况。

1).添加网络权限到你的AndroidManifest.xml文件

<uses-permission android:name="android.permission.INTERNET" />

2).选择一个网络请求库

如Retrofit, OkHttp或Volley,这里以Retrofit为例。

3).添加所选网络库的依赖到你的build.gradle文件中

dependencies {// Retrofit & Gsonimplementation 'com.squareup.retrofit2:retrofit:2.9.0'implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
}

4).创建一个模型类来表示你的数据

data class User(val name: String, val email: String)

5).定义一个接口来描述HTTP请求

import retrofit2.Call
import retrofit2.http.GETinterface ApiService {@GET("users/info")fun getUserInfo(): Call<User>
}

6).使用Retrofit构建器实例化你的服务

import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactoryobject RetrofitClient {private const val BASE_URL = "https://your.api.url/"val apiService: ApiService by lazy {Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build().create(ApiService::class.java)}
}

7).发送网络请求并处理响应

import retrofit2.Call
import retrofit2.Callback
import retrofit2.Responseclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)RetrofitClient.apiService.getUserInfo().enqueue(object : Callback<User> {override fun onResponse(call: Call<User>, response: Response<User>) {if (response.isSuccessful) {val userInfo = response.body()// 使用userInfo数据}}override fun onFailure(call: Call<User>, t: Throwable) {// 处理请求失败的情况}})}
}

13.ContentProvider

使用 ContentProvider 进行跨应用的数据共享和传递。

ContentProvider 提供了标准的接口和方法来操作数据,并可以通过 URI 进行数据的访问。

适用于需要在不同应用间共享数据的情况。

1).定义一个ContentProvider类

首先,创建一个类继承自ContentProvider并实现它的抽象方法。

class MyContentProvider : ContentProvider() {// 初始化ContentProvideroverride fun onCreate(): Boolean {// 初始化数据库等操作return true}// 查询数据override fun query(uri: Uri,projection: Array<String>?,selection: String?,selectionArgs: Array<String>?,sortOrder: String?): Cursor? {// 处理查询请求return null}// 插入数据override fun insert(uri: Uri, values: ContentValues?): Uri? {// 处理插入请求return null}// 更新数据override fun update(uri: Uri,values: ContentValues?,selection: String?,selectionArgs: Array<String>?): Int {// 处理更新请求return 0}// 删除数据override fun delete(uri: Uri,selection: String?,selectionArgs: Array<String>?): Int {// 处理删除请求return 0}// 返回MIME类型override fun getType(uri: Uri): String? {// 根据URI返回正确的MIME类型return null}
}

2).在AndroidManifest.xml中注册ContentProvider

<providerandroid:name=".MyContentProvider"android:authorities="com.example.myapp.provider"android:exported="true" />

android:authorities应该是唯一的,通常使用应用的包名作为前缀。

3).使用ContentResolver访问ContentProvider

其他应用可以使用ContentResolver来查询你的ContentProvider。

获取ContentResolver实例:

在你的应用中,你可以通过调用getContentResolver()方法来获取ContentResolver的实例。这通常在Activity或Service中进行。

val contentResolver = context.contentResolver

构建URI:

访问ContentProvider的数据时,你需要指定一个URI。这个URI指向你想要访问的数据集合或单个数据项。URI通常遵循这样的格式:content://<authority>/<path>,其中<authority>是在AndroidManifest.xml中注册ContentProvider时指定的,并且是唯一的。<path>是你希望访问的数据表或数据类型。

val uri: Uri = Uri.parse("content://com.example.myapp.provider/table_name")

查询数据:

使用ContentResolver的query()方法来请求数据。你可以指定列名、选择条件、选择参数和排序顺序。

val cursor: Cursor? = contentResolver.query(uri,projection, // String数组,代表你想要返回的列。selection, // SQL中的where子句,但不包括"WHERE"本身。selectionArgs, // 与selection中的占位符相匹配的值。sortOrder // 结果的排序方式。
)

处理返回的Cursor:

如果查询成功,query()方法将返回一个Cursor对象。通过这个Cursor,你可以遍历和读取数据。

cursor?.let {while (it.moveToNext()) {// 使用Cursor获取数据val columnValue = it.getString(it.getColumnIndex("column_name"))// 处理数据...}
}
cursor?.close() // 最后记得关闭Cursor

插入、更新和删除数据:

除了查询数据,ContentResolver还提供了insert(), update(), 和 delete()方法来进行数据的增、改、查操作。

// 插入数据
val newUri: Uri? = contentResolver.insert(uri, contentValues)// 更新数据
val rowsUpdated: Int = contentResolver.update(uri, contentValues, selection, selectionArgs)// 删除数据
val rowsDeleted: Int = contentResolver.delete(uri, selection, selectionArgs)

处理权限:

如果ContentProvider包含私有数据或者需要限制访问,你需要在AndroidManifest.xml中声明相应的权限,并在访问时请求这些权限。

安全性考虑:

当你的ContentProvider向其他应用公开数据时,需要考虑到数据安全性。确保对输入的URI进行验证,避免SQL注入等安全漏洞,并根据需要对访问进行身份验证和授权。

通过这种方式,ContentResolver和ContentProvider一起提供了一种强大的机制,允许应用之间安全、高效地共享数据。


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

相关文章

YOLOv7独家原创改进: AKConv(可改变核卷积),即插即用的卷积,效果秒杀DSConv | 论文作者邀请推广,2023年11月最新发表

💡💡💡💡💡💡💡💡💡​​​​​​​💡💡💡​​​​​​​论文作者邀请推广系列 💡💡💡💡💡💡💡💡💡💡💡💡💡💡💡 💡💡💡本文全网首发独家改进:可改变核卷积(AKConv),赋予卷积核任意数量的参数和任意采样形…

BP算法推导

例子1&#xff1a; 例子2&#xff1a; 例子3&#xff1a;

编程难点:常见问题及解决方案

目录 1 前言2 学习成本高2.1 学习成本高的问题2.2 学习成本高的解决方法 3 程序bug多3.1 程序bug多的问题 4 程序的性能调试4.1 程序的性能问题4.1 程序的性能调试方法 5 跨平台兼容性差5.1 跨平台兼容问题5.1 跨平台兼容问题的解决方法 6 解决技术难题的方法总结7 总结 1 前言…

Python语言创建爬虫代理IP池详细步骤和代码示例

目录 一、引言 二、代理IP的选择 三、使用代理IP的代码示例 四、创建代理IP池的代码示例 五、总结 一、引言 在爬虫程序中&#xff0c;代理IP的使用是避免IP被封禁、提高爬取效率的重要手段。本文将详细介绍如何使用Python语言创建一个爬虫代理IP池&#xff0c;包括代理I…

【挑战业余一周拿证】一、亚马逊云科技简介 - 第 1 节 - 模块 1 简介

CSDN 官方中文视频&#xff08;免费&#xff09;&#xff1a;点击进入 一、亚马逊云科技简介 第 1 节 - 模块 1 简介 1、讲师&#xff1a;李锦鸿 部门&#xff1a;亚马逊云科技培训与认证部门 方向&#xff1a;从事数据中心及云计算相关产品与解决方案工作 课程&#xff…

Sass 安装

文章目录 前言SASS的系统要求安装Ruby例子后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;Sass和Less &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现错误&…

力扣226. 翻转二叉树

递归 思路&#xff1a; 从根开始递归遍历二叉树&#xff0c;叶节点开始翻转&#xff1b;如果遍历到的当前的 root 节点左右两棵子树已经翻转&#xff0c;交换左右子树即可&#xff1b; /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeN…

2020年06月 Scratch(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共15题,每题2分,共30分) 第1题 执行下图程序后,“花名”列表的第3项是? A:莲花 B:丁香 C:合欢 D:月季 答案:C 列表基本知识,选C。 第2题 执行如下图所示程序后,其结果为? A: B:

C#常见的设计模式-结构型模式

引言 设计模式是软件工程中用于解决常见问题的可复用解决方案。在C#编程中&#xff0c;常见的设计模式具有广泛的应用。本篇博客将重点介绍C#中常见的结构型设计模式&#xff0c;包括适配器模式、装饰器模式、代理模式、组合模式和享元模式。 目录 引言1. 适配器模式(Adapter …

3D ACIS Modeler和HOOPS Visualize助力鲁班软件打造BIM数字化平台

鲁班软件成立于2001年&#xff0c;始终致力于BIM技术研发和推广&#xff0c;为建筑产业相关企业提供基于BIM技术的数字解决方案&#xff0c;专注打造能够支撑建筑企业集团发展的BIM数字化平台鲁班工程管理数字平台(Luban Builder)&#xff0c;以及可承载园区级或城市级的BIM、C…

Linux:创建进程 -- fork,到底是什么?

相信大家在初学进程时&#xff0c;对fork函数创建进程一定会有很多的困惑&#xff0c;比如&#xff1a; 1.fork做了什么事情?? 2.为什么fork函数会有两个返回值?3.为什么fork的两个返回值&#xff0c;会给父进程谅回子进程pid&#xff0c;给子进程返回0?4.fork之后:父子进…

借力互联网,民营医院探索互联网医疗服务的发展方向

民营医院互联网医疗服务是指利用互联网技术和平台&#xff0c;为患者提供更加便捷、高效的医疗服务。在当前数字化时代&#xff0c;互联网医疗服务正逐渐成为医疗行业的新趋势&#xff0c;也为民营医院开拓了更广阔的发展空间。下面将围绕这一主题进行讨论&#xff1a; 首先&a…

探索RockPlus SECS/GEM平台 - 赋能半导体行业设备互联

SECS/GEM协议&#xff0c;全称为半导体设备通讯标准/通用设备模型&#xff08;SECS/Generic Equipment Model&#xff09;&#xff0c;是一种广泛应用于半导体制造行业的通信协议。它定义了半导体设备与工厂主控系统&#xff08;如MES&#xff09;之间的通信方式&#xff0c;使…

供配电系统智能化监控

供配电系统智能化监控是指利用先进的监测技术、自动化控制技术、计算机网络技术等&#xff0c;对供配电系统进行实时、全方位的监测和控制&#xff0c;以实现供配电系统的安全、稳定、高效运行。 供配电系统智能化监控的主要功能包括&#xff1a; 实时数据采集&#xff1a;通过…

矢量图片转换软件Vector Magic mac中文版功能特色

Vector Magic mac是一款图片转换矢量图&#xff0c;该软件使用世界上最好的全彩色自动描摹器&#xff0c;快速准备好您的作品进行打印、绣花、剪裁等操作。 Vector Magic mac功能特色 只需上传即可在线自动将 JPG、PNG、BMP 和 GIF 位图图像转换为真正的 SVG、Eps 和 PDF 矢量…

ESXi 6.7 升级 7.0

方式一&#xff1a;esxcli方式 1.登陆exsi web界面。 启用控制台shell 2.存储-datastore-数据存储浏览器&#xff0c;上载 ESXI-7.0.0-depot.zip升级文件。记住此datastore的位置 ssh连接ESXI主机 vmware -vl 查看当前版本 查看升级包中对应的版本信息&#xff1a; es…

fatal: refusing to merge unrelated histories報錯咋辦

在 Git 中&#xff0c;如果要合并两个分支&#xff0c;而这两个分支的历史记录不相交&#xff0c;就会出现错误&#xff1a;fatal: refusing to merge unrelated histories。 要解决这个问题&#xff0c;有以下几种方法&#xff1a; 首先&#xff0c;检查一下你正在合并的两个…

目录树自动生成器 golang+fyne

go tree 代码实现请看 gitee 仓库链接 有很多生成目录树的工具&#xff0c;比如windows自带的tree命令&#xff0c;nodejs的treer&#xff0c;tree-cli等等。这些工具都很成熟、很好用&#xff0c;有较完善的功能。 但是&#xff0c;这些工具全部是命令式的&#xff0c;如果…

瑞数五代ast反混淆笔记一

第一部分 瑞数五代ast反混淆笔记一 文章目录 前言一、分析第一层js文件二、转换为switch-case三、效果图总结 前言 瑞数五代的反混淆做了很久了&#xff0c;当时写的很复杂&#xff0c;也没有记笔记&#xff0c;现在看代码都看不懂了&#xff0c;重新归顺下逻辑思路 一、分析第…

2 时间序列预测入门:GRU

0 论文地址 GRU 原论文&#xff1a;https://arxiv.org/pdf/1406.1078v3.pdf GRU&#xff08;Gate Recurrent Unit&#xff09;是循环神经网络&#xff08;RNN&#xff09;的一种&#xff0c;可以解决RNN中不能长期记忆和反向传播中的梯度等问题&#xff0c;与LSTM的作用类似&a…
最新文章