Android开发JetPack-Databinding组件

news2024/11/15 11:21:02

DataBinding介绍

  • Android开发JetPack-Databinding组件
      • 1. 什么是databinding
        • (1)简介
        • (2)意义
      • 2. databinding基本使用
        • (1)启用databinding
        • (2)定义一个布局
        • (3)创建一个User类
        • (4)改变MainActivity.kt的代码
      • 3. 通过DatabindingUtil获取到Binding
      • 4.给BaseViewFragment加载View
      • 5.编写BaseVmFragment
      • 6.布局和绑定表达式
        • (1)其他控件引用,TextView引用EditText。
        • (2)表达式中也可以引用资源内容。
        • (3)某些资源需要用到特定的类型。
      • 7.事件处理
        • 事件处理,一种为方法引用,一种为监听绑定。
        • 实例
      • 8.双向绑定
        • 双向绑定要达到的效果便是除了数据影响界面,界面变化也要使得数据发生变化。比如EditText输入内容时,绑定的数据bean要跟着变化。
      • 9.数据更新-->UI更新
        • Databinding通过使用实现Observable的数据,当数据更新的时候,自动更新UI。
        • 监听对象变化更新
      • 10.BindingAdapter
        • DataBinding支持在普通方法上添加@注解来添加自定义控件属性。
      • 11.小结

Android开发JetPack-Databinding组件

1. 什么是databinding

(1)简介

Databinding是谷歌的一个官方支持库,它允许您使用声明性格式而不是通过编程方式将布局中的UI组件绑定到应用程序中的数据源。通常在活动中使用调用UI框架方法的代码来定义布局。例如,调用findViewById()以查找TextView窗口小部件并将其绑定到变量。因为它通过在布局文件中绑定组件,您可以删除活动中的许多UI框架调用,从而使它们更易于维护。这也可以提高应用程序的性能,并有助于防止内存泄漏和空指针异常。

(2)意义

1、布局文件通常只负责UI控件的布局工作,页面中通过代码对控件需要进行各种操作,承担了绝大部分的工作量

2、DataBinding让布局文件承担了部分原本属于页面的工作,也使得布局文件和页面的耦合度进一步降低

3、使得UI控件能够直接合数据模型中的字段绑定,甚至能响应用户的交互。方便实现MVVM

2. databinding基本使用

(1)启用databinding

在模块下的build.gradle文件中,启动dataBinding。

android {
  ...
  dataBinding {
      enabled = true
  }
}

(2)定义一个布局

显示用户的姓名,年龄和性别,将普通布局文件转换为DataBinding布局文件。

转换后代码如下:

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

  <data>

      <variable
          name="user"
          type="com.example.myapplication.domain.User" />
  </data>

  <androidx.constraintlayout.widget.ConstraintLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      tools:context=".MainActivity">

      <androidx.constraintlayout.widget.Guideline
          android:id="@+id/guideline"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:orientation="horizontal"
          app:layout_constraintGuide_percent="0.10259918" />

      <androidx.constraintlayout.widget.Guideline
          android:id="@+id/guideline2"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:orientation="horizontal"
          app:layout_constraintGuide_percent="0.2" />

      <androidx.constraintlayout.widget.Guideline
          android:id="@+id/guideline3"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:orientation="horizontal"
          app:layout_constraintGuide_percent="0.3" />

      <androidx.constraintlayout.widget.Guideline
          android:id="@+id/guideline4"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:orientation="vertical"
          app:layout_constraintGuide_percent="0.3" />

      <TextView
          android:id="@+id/textView"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@string/text_name"
          app:layout_constraintBottom_toTopOf="@+id/guideline"
          app:layout_constraintEnd_toStartOf="@+id/guideline4"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toTopOf="parent" />

      <TextView
          android:id="@+id/textView2"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@string/text_age"
          app:layout_constraintBottom_toTopOf="@+id/guideline2"
          app:layout_constraintEnd_toStartOf="@+id/guideline4"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toTopOf="@+id/guideline" />

      <TextView
          android:id="@+id/textView3"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@string/text_gender"
          app:layout_constraintBottom_toTopOf="@+id/guideline3"
          app:layout_constraintEnd_toStartOf="@+id/guideline4"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toTopOf="@+id/guideline2" />

      <TextView
          android:id="@+id/textView4"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@{user.name}"
          app:layout_constraintBottom_toTopOf="@+id/guideline"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toStartOf="@+id/guideline4"
          app:layout_constraintTop_toTopOf="parent" />

      <TextView
          android:id="@+id/textView6"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@{user.gender.toString()}"
          app:layout_constraintBottom_toTopOf="@+id/guideline3"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toStartOf="@+id/guideline4"
          app:layout_constraintTop_toTopOf="@+id/guideline2" />

      <TextView
          android:id="@+id/textView7"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@{String.valueOf(user.age)}"
          app:layout_constraintBottom_toTopOf="@+id/guideline2"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toStartOf="@+id/guideline4"
          app:layout_constraintTop_toTopOf="@+id/guideline" />
  </androidx.constraintlayout.widget.ConstraintLayout>
 </layout>

(3)创建一个User类

封装用户数据。

package com.sunofbeaches.databindingdemo.domain

data class User(var name: String, var age: Int, var gender: Gender)

enum class Gender {
    FEMALE, MALE
}

(4)改变MainActivity.kt的代码

拿到布局并给User赋值。

  class MainActivity : AppCompatActivity() {

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       //如何获取到Binding,获取binding后可以给其中的变量赋值
       val binding:ActivityMainBinding = ActivityMainBinding.inflate(layoutInflater)
       //获取到View
       binding.user = User("LiMing", 30, Gender.Male)
       setContentView(binding.root)
  }
 }

请添加图片描述

3. 通过DatabindingUtil获取到Binding

(1)DataBindingUtil返回T,T是一个泛型,将其设为ActivityMainBinding,传参activity和Resource.id。

(2)ActivityMainBinding继承ViewDataBinding,返回binding。

(3)不需要设置ContentView,因为已经设置。

代码:

class MainActivity : AppCompatActivity() {
 override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      //把布局交给DataBindingUtil
      val activityMainBinding: ActivityMainBinding =
          DataBindingUtil.setContentView(this, R.layout.activity_main)
      //设置数据
      activityMainBinding.user = User("LiMing", 20, Gender.MALE)
  }
}

4.给BaseViewFragment加载View

创建一个base包,创建BaseViewFragment类继承Fragmen,创建方法返回View。

  abstract class BaseViewFragment<T : ViewDataBinding> : Fragment() {

    protected var binding: T? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = DataBindingUtil.inflate<T>(inflater, getSubLayoutId(), container, false)
        return binding!!.root
    }

    abstract fun getSubLayoutId() : Int
  }

5.编写BaseVmFragment

创建BaseVmFragment类。

  abstract class BaseVmFragment<T : ViewDataBinding,VM:ViewModel> : BaseViewFragment<T>() {

    protected lateinit var viewModel: VM

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        //创建ViewModel
        initViewModel()
        //观察数据变化--->更新UI
        abserverData()
        //设置相关的事件
        initEvent()
    }

    open fun initEvent(){
        
    }

    open fun abserverData(){

    }

    //创建ViewModel
    private fun initViewModel() {
        viewModel = ViewModelProvider(this).get(getSubVMClass())
    }

    abstract fun getSubVMClass(): Class<VM>
  }

6.布局和绑定表达式

表达式

(1)其他控件引用,TextView引用EditText。

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

  <androidx.constraintlayout.widget.ConstraintLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent">


      <androidx.constraintlayout.widget.Guideline
          android:id="@+id/guideline5"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:orientation="vertical"
          app:layout_constraintGuide_percent="0.3" />

      <androidx.constraintlayout.widget.Guideline
          android:id="@+id/guideline6"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:orientation="horizontal"
          app:layout_constraintGuide_percent="0.1" />

      <androidx.constraintlayout.widget.Guideline
          android:id="@+id/guideline7"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:orientation="horizontal"
          app:layout_constraintGuide_percent="0.2" />

      <TextView
          android:id="@+id/textView9"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@string/text_account"
          app:layout_constraintBottom_toTopOf="@+id/guideline6"
          app:layout_constraintEnd_toStartOf="@+id/guideline5"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toTopOf="parent" />

      <TextView
          android:id="@+id/textView10"
          android:text="@{inputBox.text}"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          app:layout_constraintBottom_toTopOf="@+id/guideline7"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toStartOf="@+id/guideline5"
          app:layout_constraintTop_toTopOf="@+id/guideline6" />

      <EditText
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:ems="10"
          android:id="@+id/input_box"
          android:hint="请输入用户名"
          android:inputType="textPersonName"
          app:layout_constraintBottom_toTopOf="@+id/guideline6"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toStartOf="@+id/guideline5"
          app:layout_constraintTop_toTopOf="parent" />
  </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

请添加图片描述

(2)表达式中也可以引用资源内容。

  <?xml version="1.0" encoding="utf-8"?>
  <layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="user"
            type="com.sunofbeaches.databindingdemo.domain.User" />

    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:textColor="@{@color/colorAccent}"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{@string/app_name}" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{@string/text_user_info(user.name,user.age)}" />
    </LinearLayout>
  </layout>
  class ResourcesActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      val resourcesBinding = DataBindingUtil.setContentView<ActivityResourcesBinding>(
          this,
          R.layout.activity_resources
      )
      resourcesBinding.user = User("LiMing", 20, Gender.MALE)
  }
}

(3)某些资源需要用到特定的类型。

请添加图片描述

7.事件处理

事件处理,一种为方法引用,一种为监听绑定。

首先需要修改数据的内容。

<data class="EventBinding">

  <variable
            name="textInfo"
            type="String" />

  <variable
            name="eventHandler"
            type="com.sunofbeaches.databindingdemo.EventHandlers" />
 </data>

实例

修改MainActivity的内容。

class EventActivity : AppCompatActivity() {
 override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     val eventBinding =
         DataBindingUtil.setContentView<EventBinding>(this, R.layout.activity_event)
     eventBinding.textInfo = "点击复制内容"
     eventBinding.eventHandler = EventHandlers()
 }
}

方法处理类。

class EventHandlers {
  fun onFistButtonClick(view: View) {
      println("第一个按钮点击了...")
  }

  fun onTextClickToCopy(text: String) {
      println("复制的内容是:$text")
  }
}

方法引用

<Button
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:onClick="@{eventHandler::onFistButtonClick}"
      android:text="第一个按钮点击" />

监听绑定

<TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="@{()->eventHandler.onTextClickToCopy(textInfo)}"
        android:text="@{textInfo}" />

<CheckBox
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onCheckedChanged="@{(cb, isChecked) -> eventHandler.completeChanged(cb, isChecked)}"
        android:text="选择测试" />

请添加图片描述

8.双向绑定

双向绑定要达到的效果便是除了数据影响界面,界面变化也要使得数据发生变化。比如EditText输入内容时,绑定的数据bean要跟着变化。

布局文件

<EditText
<?xml version="1.0" encoding="utf-8"?>
<layout 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">

  <data>

      <import type="com.example.myapplication.DataBean" />

      <variable
          name="databean"
          type="DataBean" />

  </data>

  <androidx.constraintlayout.widget.ConstraintLayout
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:background="#FFFFFF"
      tools:context=".MainActivity">

      <TextView
          android:id="@+id/textView"
          android:layout_width="match_parent"
          android:layout_height="30dp"
          android:layout_marginTop="30dp"
          android:gravity="center|left"
          android:paddingLeft="20dp"
          android:text="Data数据:"
          android:textSize="13dp"
          app:layout_constraintTop_toTopOf="parent" />

      <TextView
          android:id="@+id/textView2"
          android:layout_width="match_parent"
          android:layout_height="45dp"
          android:layout_marginTop="2dp"
          android:text="@{databean.data}"
          android:background="#03A9F4"
          android:gravity="left|center"
          android:paddingLeft="20dp"
          android:textColor="#FFFFFF"
          android:textSize="14dp"
          app:layout_constraintTop_toBottomOf="@+id/textView"
          tools:ignore="MissingConstraints"
          tools:layout_editor_absoluteX="0dp" />

      <EditText
          android:layout_width="match_parent"
          android:layout_height="45dp"
          android:layout_marginTop="15dp"
          android:background="#F2F2F2"
          android:text="@={databean.data}"
          android:hint="请输入数据"
          android:paddingLeft="20dp"
          android:textSize="14dp"
          app:layout_constraintTop_toBottomOf="@+id/textView2"
          tools:layout_editor_absoluteX="0dp" />

  </androidx.constraintlayout.widget.ConstraintLayout>
 </layout>

MainActivity中的代码

package com.example.myapplication;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.View;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ObservableField;

import com.example.myapplication.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

  private ActivityMainBinding activityMainBinding;
  private DataBean dataBean;

  @SuppressLint({"SetTextI18n", "InlinedApi"})
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
      
      getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

      dataBean = new DataBean(new ObservableField<String>(""));

      activityMainBinding.setDatabean(dataBean);
  }
}

DataBean中的代码

package com.example.myapplication;


import androidx.databinding.ObservableField;

public class DataBean {
  public final ObservableField<String> data;

  public DataBean(ObservableField<String> data) {
      this.data = data;
  }

  public ObservableField<String> getData() {
      return data;
  }
}

请添加图片描述

9.数据更新–>UI更新

Databinding通过使用实现Observable的数据,当数据更新的时候,自动更新UI。

class PlainObjectActivity : AppCompatActivity() {
  private lateinit var dataBinding: ActivitySimpleObserableBinding
  override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      dataBinding = DataBindingUtil.setContentView<ActivitySimpleObserableBinding>(
          this,
          R.layout.activity_simple_obserable
      )
      dataBinding.activity = this
      dataBinding.simpleUser = SimpleUser().apply {
          age.set(20)
          userName.set("Lisa")
      }
  }

  fun onButtonClick() {
      Toast.makeText(this, "更新数据...", Toast.LENGTH_SHORT).show()
      dataBinding.simpleUser?.apply {
          age.set(18)
          userName.set("LiHua")
      }
  }
}

监听对象变化更新

常用的Observable

  • ObservableBoolean

  • ObservableByte

  • ObservableChar

  • ObservableShort

  • ObservableInt

  • ObservableLong

  • ObservableFloat

  • ObservableDouble

  • ObservableParcelable

  • ObservableArrayMap

  • ObservableArrayList

    override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          dataBinding = DataBindingUtil.setContentView<ActivitySimpleObserableBinding>(
              this,
              R.layout.activity_simple_obserable
          )
          dataBinding.activity = this
          dataBinding.observableUser = ObservableObjectUser().apply {
              age = 20
              userName = "Lisa"
          }
      }
    
      fun onButtonClick() {
          Toast.makeText(this, "更新数据...", Toast.LENGTH_SHORT).show()
          dataBinding.observableUser?.apply {
              age = 18
              userName = "LiHua"
          }
      }
    }
    

10.BindingAdapter

DataBinding支持在普通方法上添加@注解来添加自定义控件属性。

(1)修饰方法, 要求方法必须public static
(2)方法参数第一个要求必须是View
(3)方法名不作要求

使用方法如下:

@BindingMethods({
     @BindingMethod(type = android.widget.ProgressBar.class, attribute = "android:indeterminateTint", method = "setIndeterminateTintList"),
     @BindingMethod(type = android.widget.ProgressBar.class, attribute = "android:progressTint", method = "setProgressTintList"),
     @BindingMethod(type = android.widget.ProgressBar.class, attribute = "android:secondaryProgressTint", method = "setSecondaryProgressTintList"),
})
public class ProgressBarBindingAdapter {
}

11.小结

databinding用来实现 vm层和v层的双向绑定关系;取代繁琐的findViewByid();绑定VM层和V层的关联关系,实现双向交互;

作者:李思雨
原文地址:https://blog.csdn.net/m0_54156164/article/details/128105290?spm=1001.2014.3001.5502

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

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

相关文章

Redis02:企业架构介绍以及redis介绍

企业架构介绍以及redis介绍NoSql概述单机Mysql的演进当今企业架构分析NoSql概述 单机Mysql的演进 1、单机Mysql的年代 90年代一个基本的网站访问量一般不会太大&#xff0c;单个数据库完全足够&#xff01;那个时候更多的去使用静态html&#xff0c;服务器没有太大的压力。这…

HCIP实验3-1:IBGP与EBGP

实验 3-1 IBGP与EBGP 学习目的 掌握区域内部BGP的配置方法掌握多区域BGP的配置方法观察BGP的邻居表和数据库掌握BGP更新源的配置方法掌握EBGP多跳的配置方法观察IBGP和EBGP中路由的下一跳的变化掌握IBGP中下一跳的配置掌握BGP的Network命令的配置方法 拓扑图 场景 你是公司…

open label file.(This can be normal only if you use MScoco)

E:\yolov4-rubish\darknet\our_data\ImagesAug 把标签的txt文件和Jpg文件放在同一个文件夹

Kafka 入门知识,看这一篇就够了(上)

目录01 初识 Kafka02 topic & partition03 Kafka 分布式最近在学习 Kafka&#xff08;别问&#xff0c;问就是公司在用 &#xff09;&#xff0c;将学习过程中的笔记整理出来分享给大家&#xff0c;就当是入入门 01 初识 Kafka Kafka 最早是由 LinkedIn 公司开发的&#x…

python中numpy数组形状和计算

1. numpy数组形状 数组可以理解为是矩阵&#xff0c;所以会涉及几行几列 import numpy as np import randomt1 np.array([[1,2,3],[4,5,6]]) print(t1) print(t1.shape)在这段逻辑里&#xff0c;t1是个数组&#xff0c;输出结果后 (2, 3)表示的就是这个数组是一个2行3列的矩…

计算机系统基础实验——数据的机器级表示(计算浮点数 f 的绝对值[f])

题目要求&#xff1a; 这个函数计算浮点数f的绝对值[f]。如果f是NaN&#xff0c;函数应该简单的返回f。 Unsigned float_abs (unsiged f) { /**************/ return/*******/; } 先分析题目&#xff0c;题目有两个要求&#xff1a; 1.判断f是否是NAN类型&#xff0c;如果是返…

文件管理,给文件名称插入纯数字详细步骤

在日常办公过程中&#xff0c;我们经常会需要对文件名称进行重命名&#xff0c;如何给文件插入纯数字呢&#xff1f;一两个文件还好可以自定义重命名&#xff0c;面对大量文件的时候&#xff0c;怎么在文件名称中插入纯数字呢&#xff1f;一起来看看吧&#xff01; 第一步&…

这 5 本数据分析书籍,都是经典中的经典

下面要推荐的 5 本数据分析书籍对于数据分析领域而言&#xff0c;经典、经典、还是经典。 强烈建议先收藏&#xff0c;再观看。 《深入浅出数据分析》 数据分析入门第一本。 本书构思跌宕起伏&#xff0c;行文妙趣横生&#xff0c;无论是职场老手&#xff0c;还是业界新人&…

S2SH小区物业管理理系统计算机毕业论文Java项目源码下载

&#x1f496;&#x1f496;更多项目资源&#xff0c;最下方联系我们✨✨✨✨✨✨ 目录 Java项目介绍 资料获取 Java项目介绍 计算机毕业设计java毕设之S2SH小区物业系统_哔哩哔哩_bilibili计算机毕业设计java毕设之S2SH小区物业系统共计2条视频&#xff0c;包括&#xff1…

香农-范诺编码(Shannon–Fano Coding)

香农-范诺编码香农-范诺编码简介算法示例香农-范诺编码 简介 香农-范诺编码&#xff08;Shannon–Fano Coding&#xff09;是一种基于一组符号集及其出现的或然率&#xff08;估量或测量所得&#xff09;&#xff0c;从而构建前缀码的技术。 一般过程&#xff1a;符号从最大可…

太强了!GitHub上白嫖的SpringCloud微服务进阶宝典,啃完感觉能吊锤面试官!

自 2014 年起&#xff0c;微服务技术一直火热至今。随着越来越完善的微服务技术栈的发布&#xff0c;以及越来越多的微服务项目实际的落地和上线&#xff0c;使用 Java 技术栈的企业应该都在尝试或者已经落地了各自的微服务项目。同时&#xff0c;通过招聘网站的信息和每次面试…

正确理解线程WAITING状态

正确理解线程WAITING状态 今天来学习下&#xff0c;Java的线程状态&#xff0c;重点讨论下thread.state.WAITING。讨论下线程如何进入此状态&#xff0c;以及它们之间的区别。最后&#xff0c;我们进一步了解java.util.concurrent.locks.LockSupport&#xff0c;它提供了几种用…

【分布式能源的选址与定容】基于非支配排序多目标遗传优化算法求解分布式能源的选址与定容(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

AOP通知获取数据

之前说到了AOP可以对原始方法进行增强&#xff0c;那么AOP是否可以获取到原始方法的数据并对原始方法的数据利用增强方法进行处理呢&#xff1f;我们将从获取参数、获取返回值和获取异常三个方面来研究。 首先&#xff0c;我们可以知道&#xff0c;所有的通知类型都可以获取参数…

微服务框架 SpringCloud微服务架构 10 使用Docker 10.6 容器命令练习

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构10 使用Docker10.6 容器命令练习10.6.1 直接开干10 使用Docker 10.6 容器…

阿里“重推”的Spring+Boot+MVC+CloudAlibaba学习手册,开源下载

Spring框架自诞生以来一直备受开发者青睐&#xff0c;有人亲切的称之为&#xff1a;Spring 全家桶。Spring更是避免了重复造轮子的工作并跟随着互联网行业的发展做出不断的更新&#xff0c;很多研发人员把spring看作心目中最好的Java项目&#xff0c;没有之一。 可以毫不夸张的…

VS Code 扩展开发如何保持用户视觉体验一致

本文介绍如何在 VS Code 插件的 webview 中加载本地的资源文件&#xff0c;并如何使用 VS Code 自身的 UI 来实现用户视觉体验的一致。 背景 最近想做一个 VS Code 的插件用来简便我使用 VS Code 来编辑 Markdown 博客的体验&#xff0c;在设计插件的过程中&#xff0c;因为需…

计算机毕业论文Java项目源码下载S2SH智慧社区管理系统[包运行成功]

&#x1f496;&#x1f496;更多项目资源&#xff0c;最下方联系我们✨✨✨✨✨✨ 目录 Java项目介绍 资料获取 Java项目介绍 《基于S2SH实现的智慧社区管理系统》该项目采用技术jsp、strust2、Spring、hibernate、tomcat服务器、mysql数据库 &#xff0c;项目含有源码、答…

力扣hot100——第6天:32最长有效括号、33搜索旋转排序数组、34在排序数组中查找元素的第一个和最后一个位置

文章目录1.32最长有效括号1.1.题目1.2.解答2.33搜索旋转排序数组2.1.题目2.2.解答3.34在排序数组中查找元素的第一个和最后一个位置【代码随想录已刷】1.32最长有效括号 参考&#xff1a;力扣题目链接&#xff1b;题解1&#xff0c;题解2 1.1.题目 1.2.解答 这道题目官方的题…

FAT12文件系统

简介 FAT12文件系统是指&#xff1a;在磁盘上规定一种特定的存储格式&#xff0c;这种存储格式高效方便&#xff0c;功能强大&#xff0c;因此形成了统一的规定。 基础知识 具体来说FAT12文件系统为1.44M的软盘设计。1.44M的软盘有2880个扇区&#xff0c;一个扇区有512个字节&…