Android学习进阶
UI组件进阶
使用RecyclerView和Adapter显示列表数据
RecyclerView
是Android开发中用于显示列表数据的一个灵活且高效的组件。与其前身ListView
相比,RecyclerView
引入了更加复杂的布局排列和动画支持,使得创建高度定制化的列表和网格布局变得更加简单。使用RecyclerView
需要配合Adapter
来显示数据。以下是实现RecyclerView
显示列表数据的基本步骤:
1. 添加RecyclerView依赖
首先,确保你的项目中包含了RecyclerView
库。打开你的build.gradle
(Module: app)文件,并添加以下依赖:
dependencies {implementation 'androidx.recyclerview:recyclerview:1.2.1'
}
请检查是否有最新版本的RecyclerView
依赖可用,并使用最新版本。
2. 添加RecyclerView到布局文件
在你的布局文件中添加RecyclerView
组件。例如,在activity_main.xml
中:
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/my_recycler_view"android:layout_width="match_parent"android:layout_height="match_parent"/>
3. 创建列表项布局
为RecyclerView
中每个项(item)创建一个布局文件。例如,创建一个item_view.xml
文件:
<?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="wrap_content"android:orientation="horizontal"android:padding="16dp"><TextViewandroid:id="@+id/item_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="18sp"/>
</LinearLayout>
4. 创建Adapter
创建一个Adapter
类继承自RecyclerView.Adapter
,并实现必要的方法:onCreateViewHolder()
, onBindViewHolder()
, getItemCount()
。这个Adapter
负责将数据绑定到每个ViewHolder
中。
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {private String[] mDataset;// 提供合适的构造器(取决于数据集的类型)public MyAdapter(String[] myDataset) {mDataset = myDataset;}// 创建新视图(由布局管理器调用)@Overridepublic MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {// 创建一个新视图View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view, parent, false);return new MyViewHolder(itemView);}// 替换视图的内容(由布局管理器调用)@Overridepublic void onBindViewHolder(MyViewHolder holder, int position) {// 获取元素数据集在这个位置的数据,并替换视图的内容holder.textView.setText(mDataset[position]);}// 返回数据集的大小(由布局管理器调用)@Overridepublic int getItemCount() {return mDataset.length;}// 提供对视图的引用public static class MyViewHolder extends RecyclerView.ViewHolder {public TextView textView;public MyViewHolder(View itemView) {super(itemView);textView = itemView.findViewById(R.id.item_text);}}
}
5. 在Activity中使用RecyclerView
在你的Activity
中设置RecyclerView
和Adapter
:
public class MainActivity extends AppCompatActivity {private RecyclerView recyclerView;private RecyclerView.Adapter adapter;private RecyclerView.LayoutManager layoutManager;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);recyclerView = findViewById(R.id.my_recycler_view);// 使用这个设置来提高性能,如果你知道内容不会改变布局大小recyclerView.setHasFixedSize(true);// 使用线性布局管理器layoutManager = new LinearLayoutManager(this);recyclerView.setLayoutManager(layoutManager);// 指定adapteradapter = new MyAdapter(new String[]{"Data 1", "Data 2", "Data 3"});recyclerView.setAdapter(adapter);}
}
这段代码设置了一个简单的RecyclerView
,它使用线性布局显示一个字符串数组中的数据。
总结
RecyclerView
是展示集合数据的强大工具,它的灵活性和扩展性使得创建复杂的列表和网格布局变得容易。通过自定义Adapter
和ViewHolder
,你可以高度定制每个列表项的展示方式,包括布局和动画效果。此外,RecyclerView
还支持添加分隔符、处理点击事件等高级功能。
Fragment的使用和与Activity的交互
Fragment 的基本使用
Fragment
是一种可以在Activity
内部使用的可复用组件,它有自己的生命周期、接收输入事件,并且可以添加到Activity
布局中。Fragment
使得在一个Activity
中组合多个组件以及在多个Activity
之间复用同一个组件成为可能。
创建 Fragment
-
定义 Fragment 类:扩展
Fragment
类,并重写关键的生命周期方法,如onCreateView()
,在其中通过布局填充器加载Fragment
的布局。
public class ExampleFragment extends Fragment {@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_example, container, false);}
}
Fragment 布局:为Fragment
创建一个XML布局文件,例如fragment_example.xml
。
<TextView xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:text="Hello from the Fragment"/>
在 Activity 布局中声明:在Activity
的布局文件中,使用<fragment>
标签声明Fragment
,或者在Activity
的代码中动态添加。
静态添加:
<fragment android:name="com.example.ExampleFragment"android:id="@+id/example_fragment"android:layout_width="match_parent"android:layout_height="match_parent" />
动态添加:
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
与 Activity 的交互
Fragment
与Activity
的交互通常通过以下几种方式实现:
-
通过 Activity 传递数据给 Fragment:
- 可以在创建
Fragment
的实例时通过Bundle
设置参数。
- 可以在创建
ExampleFragment fragment = new ExampleFragment();
Bundle args = new Bundle();
args.putInt("someInt", 123);
fragment.setArguments(args);
Fragment 回调到 Activity:
- 定义一个回调接口,并让
Activity
实现它。然后在Fragment
内调用Activity
的回调方法。
public class ExampleFragment extends Fragment {CallbackInterface callback;@Overridepublic void onAttach(Context context) {super.onAttach(context);try {callback = (CallbackInterface) context;} catch (ClassCastException e) {throw new ClassCastException(context.toString()+ " must implement CallbackInterface");}}public interface CallbackInterface {void onSomeEvent();}
}
然后在Activity
中实现这个接口:
public class MainActivity extends AppCompatActivity implements ExampleFragment.CallbackInterface {@Overridepublic void onSomeEvent() {// 处理回调事件}
}
使用 ViewModel:
ViewModel
可以用于Activity
和所有的Fragment
之间共享数据。它遵循观察者模式,当数据变化时通知UI进行更新。
public class SharedViewModel extends ViewModel {private final MutableLiveData<Integer> selected = new MutableLiveData<Integer>();public void select(int item) {selected.setValue(item);}public LiveData<Integer> getSelected() {return selected;}
}
然后Activity
和Fragment
都可以观察这个ViewModel
中的数据变化。
总结
Fragment
为创建动态和可复用的UI组件提供了极大的灵活性。通过合理使用Fragment
,你可以使你的应用更加模块化,更容易适应不同的屏幕尺寸和方向。与Activity
的交互使得组件之间的数据传递和事件处理成为可能,ViewModel
的使用进一步简化了这种交互,使数据管理变得更加高效和简单。
网络编程
学习如何使用HttpURLConnection或OkHttp进行网络请求
在Android开发中,进行网络请求是一项常见需求。HttpURLConnection
和OkHttp
是两种流行的方式来执行这些请求。下面分别介绍如何使用这两种方法。
使用 HttpURLConnection
HttpURLConnection
是Java标准库的一部分,可以直接在Android项目中使用。它支持基本的GET、POST等HTTP方法。
示例:使用HttpURLConnection发起GET请求
new Thread(new Runnable() {@Overridepublic void run() {HttpURLConnection urlConnection = null;try {URL url = new URL("http://www.example.com");urlConnection = (HttpURLConnection) url.openConnection();urlConnection.setRequestMethod("GET");InputStream in = new BufferedInputStream(urlConnection.getInputStream());String response = readStream(in);// 处理响应...} catch (Exception e) {e.printStackTrace();} finally {if (urlConnection != null) {urlConnection.disconnect();}}}
}).start();
这个例子展示了如何在一个新线程中发起一个简单的GET请求,并读取响应。注意网络请求必须在非UI线程中执行。
使用 OkHttp
OkHttp
是一个第三方库,由Square开发,相比HttpURLConnection
,它提供了更简洁的API、更快的速度和更丰富的功能,如连接池、GZIP压缩和请求缓存等。
首先,添加OkHttp的依赖到你的build.gradle
文件:
dependencies {implementation 'com.squareup.okhttp3:okhttp:4.9.0'
}
示例:使用OkHttp发起GET请求
OkHttpClient client = new OkHttpClient();String run(String url) throws IOException {Request request = new Request.Builder().url(url).build();try (Response response = client.newCall(request).execute()) {return response.body().string();}
}new Thread(new Runnable() {@Overridepublic void run() {try {String response = run("http://www.example.com");// 处理响应...} catch (IOException e) {e.printStackTrace();}}
}).start();
这个例子展示了如何使用OkHttp发起一个GET请求,并同样需要在非UI线程中执行。
异步请求
对于OkHttp,进行异步请求和处理响应更为方便,只需要使用enqueue
方法而不是execute
,并提供一个Callback
:
OkHttpClient client = new OkHttpClient();Request request = new Request.Builder().url("http://www.example.com").build();client.newCall(request).enqueue(new Callback() {@Overridepublic void onFailure(Call call, IOException e) {e.printStackTrace();}@Overridepublic void onResponse(Call call, Response response) throws IOException {if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);// 处理响应...}
});
这样就不需要手动创建新线程,OkHttp会自动异步执行请求,并在回调中返回结果。
总结
HttpURLConnection
是一个基本的网络请求工具,直接内置于Java中,适合简单的网络操作和对第三方库依赖要求较低的场景。而OkHttp
提供了更强大的功能和更好的性能,适合需要复杂网络操作、性能优化和更好体验的应用。选择哪一个,取决于你的具体需求和偏好。在实际开发中,由于OkHttp
的强大和易用性,它通常是更受欢迎的选择。
理解JSON数据格式,使用Gson或Jackson解析JSON数据
理解 JSON 数据格式
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScript的对象字面量规范,但独立于语言,因此许多编程语言都有JSON数据格式的解析和生成支持。JSON格式在网络传输数据时特别有用,如API请求的响应通常就是JSON格式。
一个简单的JSON对象例子:
{"name": "John Doe","age": 30,"isStudent": false,"courses": ["Math", "Science"],"address": {"street": "123 Main St","city": "Anytown"}
}
使用 Gson 解析 JSON
Gson是Google提供的用于Java对象和JSON数据之间转换的一个库。它能够将一个JSON字符串转换成等价的Java对象,或者将Java对象转换成其JSON表示形式。
添加 Gson 依赖
首先,在build.gradle
文件中添加Gson的依赖:
dependencies {implementation 'com.google.code.gson:gson:2.8.6'
}
解析 JSON 示例
假设有一个JSON表示的用户信息,我们想要将其解析为一个Java对象。
定义一个Java类来表示用户:
public class User {private String name;private int age;private boolean isStudent;private List<String> courses;private Address address;// Address类public static class Address {private String street;private String city;// getters 和 setters}// getters 和 setters
}
使用Gson来解析JSON字符串:
String json = "{...}"; // JSON数据
Gson gson = new Gson();
User user = gson.fromJson(json, User.class);
使用 Jackson 解析 JSON
Jackson是另一个流行的Java库,用于处理JSON。与Gson类似,它也可以轻松地将JSON字符串转换为Java对象,或将Java对象序列化为JSON字符串。
添加 Jackson 依赖
dependencies {implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.3'
}
解析 JSON 示例
使用Jackson解析同样的JSON数据:
String json = "{...}"; // JSON数据
ObjectMapper objectMapper = new ObjectMapper();
User user = objectMapper.readValue(json, User.class);
JSON 解析库选择
Gson和Jackson都是处理JSON数据的优秀库,它们提供了丰富的API和灵活的配置。选择哪个主要取决于个人偏好以及特定项目的需求。Gson通常使用起来更简单一些,而Jackson在处理复杂的JSON结构时提供了更多的功能和更高的性能。无论选择哪个,它们都大大简化了JSON数据的处理过程。
数据存储
学习SharedPreferences的使用,用于保存轻量级的本地数据
SharedPreferences
是Android平台上一个轻量级的存储方案,主要用于保存应用的配置数据或者是少量的数据需要持久化,比如用户设置、应用内的简单状态等。SharedPreferences
以键值对(Key-Value)的形式存储数据,支持基本的数据类型,如boolean
、float
、int
、long
、String
及它们的集合。
使用SharedPreferences存储数据
要使用SharedPreferences
存储数据,可以通过Context
的getSharedPreferences
方法获取SharedPreferences
的实例。这个方法需要两个参数:首先是文件名(如果文件不存在,Android会创建一个),其次是操作模式(通常是MODE_PRIVATE
,表示只有当前的应用可以访问这个文件)。
示例:保存数据
SharedPreferences sharedPreferences = getSharedPreferences("MyPrefs", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();editor.putString("key_name", "John Doe");
editor.putInt("key_age", 30);
editor.putBoolean("key_is_student", false);editor.apply(); // 或者 editor.commit();
getSharedPreferences
方法用于获取一个SharedPreferences
实例。- 使用
edit()
方法获得SharedPreferences.Editor
对象,然后通过这个对象添加或修改键值对。 - 调用
apply()
或commit()
提交更改。apply()
是异步的,没有返回值,而commit()
是同步的,会返回一个布尔值表示操作是否成功。
使用SharedPreferences读取数据
要从SharedPreferences
读取数据,可以使用相应的get
方法,如getString
、getInt
等。如果键不存在,可以为这些方法提供一个默认值。
示例:读取数据
SharedPreferences sharedPreferences = getSharedPreferences("MyPrefs", MODE_PRIVATE);String name = sharedPreferences.getString("key_name", "No Name");
int age = sharedPreferences.getInt("key_age", 0);
boolean isStudent = sharedPreferences.getBoolean("key_is_student", true);
在这个示例中,如果SharedPreferences
中不存在对应的键,getString
方法将返回"No Name",getInt
将返回0,getBoolean
将返回true
。
注意事项
SharedPreferences
适合存储轻量级的数据,但不适合存储大量数据或复杂的数据结构。- 存储和读取操作都是同步进行的,可能会阻塞主线程。因此,如果有大量数据需要读写,建议在子线程中进行操作,尽管
apply()
方法已经是异步执行的。 - 使用
SharedPreferences
时,数据是以明文形式保存的,因此不应该用来存储敏感信息,如用户密码。
SharedPreferences
是实现数据持久化的一种简单而有效的方法,特别适合于保存少量的配置信息或状态数据。
学习SQLite数据库的使用,进行数据的增、删、改、查操作
SQLite是一个轻量级的数据库,它存储在单个磁盘文件上。在Android中,SQLite被广泛用于数据持久化需求,支持标准的SQL语法,并提供了一套Java API,使得在Android应用中进行数据库操作变得简单。
创建 SQLite 数据库
在Android中,通常通过扩展SQLiteOpenHelper
类来创建数据库和表。这个类提供了onCreate()
和onUpgrade()
两个回调函数,用于数据库的创建和版本管理。
public class DBHelper extends SQLiteOpenHelper {private static final String DATABASE_NAME = "example.db";private static final int DATABASE_VERSION = 1;public DBHelper(Context context) {super(context, DATABASE_NAME, null, DATABASE_VERSION);}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL("CREATE TABLE contacts (" +"_id INTEGER PRIMARY KEY," +"name TEXT," +"email TEXT)");}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {db.execSQL("DROP TABLE IF EXISTS contacts");onCreate(db);}
}
插入数据
使用getWritableDatabase()
获取SQLiteDatabase
对象,然后通过insert()
方法或执行SQL
语句插入数据。
DBHelper dbHelper = new DBHelper(context);
SQLiteDatabase db = dbHelper.getWritableDatabase();ContentValues values = new ContentValues();
values.put("name", "John Doe");
values.put("email", "john@example.com");long newRowId = db.insert("contacts", null, values);
查询数据
查询数据通常使用query()
方法或直接执行SQL
查询语句,并通过Cursor
遍历查询结果。
SQLiteDatabase db = dbHelper.getReadableDatabase();Cursor cursor = db.query("contacts", // 表名称new String[] { "_id", "name", "email" }, // 要查询的列null, // WHERE子句null, // WHERE子句的参数null, // GROUP BY子句null, // HAVING子句null // ORDER BY子句
);List<String> names = new ArrayList<>();
while(cursor.moveToNext()) {String name = cursor.getString(cursor.getColumnIndexOrThrow("name"));names.add(name);
}
cursor.close();
更新数据
更新数据可以使用update()
方法或直接执行SQL
语句。
SQLiteDatabase db = dbHelper.getWritableDatabase();ContentValues values = new ContentValues();
values.put("email", "johndoe@example.com");String selection = "name LIKE ?";
String[] selectionArgs = { "John Doe" };int count = db.update("contacts",values,selection,selectionArgs);
删除数据
删除数据可以使用delete()
方法或直接执行SQL
语句。
SQLiteDatabase db = dbHelper.getWritableDatabase();String selection = "name LIKE ?";
String[] selectionArgs = { "John Doe" };int deletedRows = db.delete("contacts", selection, selectionArgs);
注意事项
- 执行数据库操作(尤其是写入和更新操作)时,建议使用事务来保证数据的一致性。
- 执行完数据库操作后,记得关闭
Cursor
和SQLiteDatabase
对象,以释放资源。 - 对于复杂的数据库操作和管理,可以考虑使用Room Persistence Library,它是一个在SQLite之上的抽象层,提供了更简洁的API和编译时的SQL检查。
使用SQLite数据库,可以在Android应用中有效地进行数据持久化操作,对于需要存储大量结构化数据的应用尤其有用。
Android的异步处理
理解并使用AsyncTask和Handler进行异步任务处理
在Android开发中,异步任务处理是常见需求,主要用于执行耗时操作(如网络请求、数据库操作等),而不阻塞主线程(UI线程)。AsyncTask
和Handler
是实现这一目标的两种常用方法。
AsyncTask
AsyncTask
是一个抽象的泛型类,它允许你在后台线程上执行长时间运行的操作,并在完成后将结果发布到UI线程。不过,从Android 11(API级别30)开始,AsyncTask
已被标记为过时(deprecated),建议使用其他现代化的方式,如java.util.concurrent
或Kotlin 协程。
使用AsyncTask的基本步骤
- 定义一个继承
AsyncTask
的类:指定输入参数、进度和结果的类型。 - 实现
doInBackground
方法:在这里执行后台任务。 - (可选)实现
onPreExecute
、onPostExecute
和onProgressUpdate
方法:在UI线程上执行操作,如初始化、更新进度和处理结果。
private static class ExampleAsyncTask extends AsyncTask<Void, Void, String> {@Overrideprotected void onPreExecute() {super.onPreExecute();// 在UI线程执行初始化操作}@Overrideprotected String doInBackground(Void... voids) {// 执行耗时后台任务return "Result";}@Overrideprotected void onPostExecute(String result) {super.onPostExecute(result);// 使用后台任务的结果在UI线程上执行操作}
}
执行AsyncTask
:
new ExampleAsyncTask().execute();
Handler
Handler
是Android中处理线程间通信的另一种方式,它允许你发送和处理Message
和Runnable
对象与一个MessageQueue
关联的线程。Handler
常用于在工作线程完成任务后更新UI。
使用Handler的基本步骤
- 创建
Handler
实例:在主线程(通常是在Activity
或Fragment
中)创建Handler
实例来处理消息或运行代码。 - 在工作线程中使用
Handler
发送消息或执行Runnable。
// 在主线程创建Handler
Handler handler = new Handler(Looper.getMainLooper());// 工作线程执行任务
new Thread(new Runnable() {@Overridepublic void run() {// 执行耗时任务// 任务完成,通知UI线程更新handler.post(new Runnable() {@Overridepublic void run() {// 在UI线程执行操作}});}
}).start();
总结
- AsyncTask:适用于简单的异步任务,尤其是那些直接与UI相关的。然而,因为
AsyncTask
已被标记为过时,建议使用更现代的并发解决方案。 - Handler:适用于复杂的线程间通信和对于UI的定时更新或处理。
Handler
是处理线程间通信的强大工具,但使用时需要更多的注意事项,特别是与线程和消息循环相关的。
对于现代Android开发,推荐使用java.util.concurrent
中的类(如Executor
、ThreadPoolExecutor
)和Kotlin协程,这些方法提供了更强大、更灵活和更简洁的并发和异步处理能力。
相关文章:
Android学习进阶
UI组件进阶 使用RecyclerView和Adapter显示列表数据 RecyclerView是Android开发中用于显示列表数据的一个灵活且高效的组件。与其前身ListView相比,RecyclerView引入了更加复杂的布局排列和动画支持,使得创建高度定制化的列表和网格布局变得更加简单。…...

“低代码+平台”:驱动企业数字化转型与创新的新引擎
“低代码平台”作为一种新兴的软件开发范式,正逐渐成为企业快速响应市场变化、优化业务流程、提升数字化水平的重要手段。它的价值在于,将传统软件开发的复杂性大大降低,赋予了非技术人员或轻量级开发者快速构建应用的能力,并能灵…...
python代码截取任意页的pdf
python代码把截取任意页的pdf:比如你有一个pdf文件1.pdf,共有30页,但是,你想把其中的10-20页截取出来保存成新的pdf,名为2.pdf,可以使用下面代码 from PyPDF2 import PdfReader, PdfWriter# 输入和输出文件…...
速盾:cdn加速后真实ip会暴漏吗?
CND(内容分发网络)是一种通过将内容分发到全球各地的服务器来加速网站访问的技术。当用户请求访问一个网站时,CDN会将静态资源(如图片、视频、脚本等)缓存在离用户最近的服务器上,从而提高网站的加载速度。…...

ATA-5310前置微小信号放大器在红外线传感器中的应用
当涉及到红外线传感器时,前置微小信号放大器扮演着关键的角色。红外线传感器是一种用于探测和测量红外辐射的设备,它们通常用于热成像、物体检测、温度测量、动作检测等应用中。前置微小信号放大器在红外线传感器中的应用具有重要意义,下面将…...
【黑马程序员】Python多任务
文章目录 多进程多进程使用流程导入包Process进程类说明 获取进程编号目的常用操作 获取进程名进程注意点进程之间不共享全局变量主进程会等待子进程结束之后再结束设置守护主进程 多线程threading模块线程注意点线程之间执行是无序的主线程会等待所有的子线程执行结束在结束线…...
前端与后端具备能力的区别
前端与后端具备能力的区别 在软件开发领域,前端和后端是两个至关重要的部分,它们各自承担着不同的职责和任务。前端主要负责与用户交互的界面设计和实现,而后端则负责处理数据和业务逻辑。因此,前端和后端开发者需要具备不同的技…...

【蓝桥杯】第15届蓝桥杯青少组stema选拔赛C++中高级真题答案(20240310)
一、选择题 第 1 题 第 2 题 表达式1000/3的结果是( A )。 A.333 B.333.3 C.334 D.333.0 第 3 题 下列选项中,判断a等于1并且b等于1正确的表达式是( B )。 A.!((a!1)&&(b!1)) B.!((a!1)||(b!1)) C.!(a1)&&(b1) D.(a1)&&(b1) 【解析】 A…...
20240319金融读报:金融助力农业科创企业风控模型
1、农发行2023年第二十期金融债券票面利率为2.85% 2、农业生产现代化转型-》农机:新疆尉犁县超级棉田里,农业无人机、采棉打包机、棉田打顶机器人等现代化机械设施,让两个人收种3000亩棉田成为了可能(金融机构可以结合农机购置补贴…...
React.js快速入门教程
React.js 是一个流行的 JavaScript 库,用于构建用户界面。以下是一个简单的 React.js 快速入门教程: 步骤 1:安装 Node.js 和 npm 首先,确保你的计算机上安装了 Node.js 和 npm(Node 包管理器)。你可以从…...
Jenkins构建时报错:Build step ‘Execute shell‘ marked build as failure
1.磁盘空间不足导致报错。 2.默认情况下,Jenkins采取 /bin/sh -xe 这种方式 -x 将打印每一个命令;另一个选项 -e,当任何命令以非零值(当任何命令失败时)退出代码时,这会导致shell立即停止运行脚本。 解决…...

C语言复杂度(个人笔记)
时间复杂度主要衡量一个算法的运行快慢. 空间复杂度主要衡量一个算法运行所需要的额外空间. 时间复杂度 算法中的基本操作的执行次数,为算法的时间复杂度. 只需要大概执行次数,我们使用大O的渐进表示法。(看谁对数学表达式的影响最大) 空间复杂度 是…...
与AI机器共存的三个层次
概述 当前我们无法不与AI机器共存。 或者说,在不远的近日,不能与AI机器和谐共处的人,就有可能会被淘汰。 新的生产革命,或许已经到来,只是我们身在此山中,当局者迷而已。 三个层次 API(Application Pr…...

python网络爬虫实战教学——requests的使用(1)
文章目录 专栏导读1、前言2、get请求3、抓取网页4、抓取二进制数据5、请求头 专栏导读 ✍ 作者简介:i阿极,CSDN 数据分析领域优质创作者,专注于分享python数据分析领域知识。 ✍ 本文录入于《python网络爬虫实战教学》,本专栏针对…...

腾讯云COS - 前端上传文件到 COS 跨域问题
问题描述 原因分析 因为我本地的地址是:http://localhost:9528 而发送请求时的地址是:http://132-1307119153.cos.ap-beijing.myqcloud.com/tu.jpg 域名不同,自然而然就出现了跨域的问题! 解决方案 先点击对象存储 - 安全设置…...

【笔记】Python学习记录
Python学习记录 Hello World变量简单数据类型字符串大小写转换插入变量Tab和Enter删除前后空格删除前后缀 Hello World 老调调了,如何在终端输出信息呢? print("Hello World")Hello World变量 变量命名遵从代码变量命名通则,几乎…...

力扣每日一题 2024/3/21 频率跟踪器
题目描述 用例说明 思路讲解 看到统计数字频率或者出现次数很容易想到用哈希表,但是一个哈希表count将数字和数字出现次数映射起来似乎不太够,如果需要统计数字出现次数的频率的话还是需要进行一次遍历,时间复杂度为O(n),有没有常…...
基于SpringBoot 实现指标监控及日志管理
添加Actuator功能 Spring Boot Actuator可以帮助程序员监控和管理SpringBoot应用,比如健康检查、内存使用情况统计、线程使用情况统计等。我们在SpringBoot项目中添加Actuator功能,即可使用Actuator监控 项目,用法如下: 在被监…...
Linux之看门狗
1、什么是看门狗? 在Linux系统中,看门狗机制主要包括硬件看门狗、软件看门狗和看门狗守护进程三个部分。硬件看门狗是一个独立的计时器设备,用于监视系统的运行状态。如果系统长时间没有发送喂狗信号,硬件看门狗将执行预设的动作…...

第十九章 TypeScript 装饰器Decorator
Decorator 装饰器是一项实验性特性,在未来的版本中可能会发生改变 它们不仅增加了代码的可读性,清晰地表达了意图,而且提供一种方便的手段,增加或修改类的功能 若要启用实验性的装饰器特性,你必须在命令行或tsconfig…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...