Android Mvp案例解析

目录

    • 后端数据接口
      • 数据格式
    • App客户端
      • 布局逻辑
        • 主界面布局
      • M(Model)
      • V(View)
      • P(Presenter)
      • Okhttp+Retrofit+RxJava网络http请求
    • Mvp架构-初学者
      • MVP架构的契约者

后端数据接口

接口地址:https://apis.tianapi.com/caipu/index

请求示例:https://apis.tianapi.com/caipu/index?key=你的APIKEY&word=黄瓜

支持协议:http/https

请求方式:get/post

返回格式:utf-8 json

数据格式

{"code": 200,"msg": "success","result": {"curpage": 1,"allnum": 5,"newslist": [{"id": "90e761e707dd996c431992c8e2a0a88b","ctime": "2023-07-07 08:29","title": "为避免轨道碰撞 SpaceX星链卫星6个月内“让路”","description": "7月7日消息,在过去6个月里,为了避免轨道碰撞,埃隆·马斯克(ElonMusk)旗下SpaceX公司的星链卫星机动次数激增,这引发了人们对卫星长期可持续性运行的担忧,因为未来几年将有数万颗新卫星进入轨道。在最近向美国联邦通信委员会(FCC...[]","source": "网易科技","picUrl": "https://nimg.ws.126.net/?url=http%3A%2F%2Fcms-bucket.ws.126.net%2F2023%2F0707%2F0f703849p00rxeh90001cc0009c0070c.png&thumbnail=200y140&quality=100&type=jpg","url": "https://www.163.com/tech/article/I91GDFVG00097U81.html"},{"id": "e8e49d6dd77be1a6ea82929a14abe6ef","ctime": "2023-07-07 06:32","title": "推特指责 Meta 挖角员工创建 Threads","description": "","source": "网易科技","picUrl": "https://nimg.ws.126.net/?url=http%3A%2F%2Fbjnewsrec-cv.ws.126.net%2Flittle730693cc23fj00rxebr3004xc000fw00lcg.jpg&thumbnail=200y140&quality=100&type=jpg","url": "https://www.163.com/dy/article/I919NRS10511B8LM.html"},{"id": "55cf44c545e02e8d9fc30e8b07980d3d","ctime": "2023-07-06 21:08","title": "分析人士:Meta的Threads对马斯克的Twitter构成","description": "","source": "网易科技","picUrl": "https://nimg.ws.126.net/?url=http%3A%2F%2Fbjnewsrec-cv.ws.126.net%2Flittle32088c42c3cj00rxdlrp000xc000sg00hgg.jpg&thumbnail=200y140&quality=100&type=jpg","url": "https://www.163.com/dy/article/I909EBMH0511B8LM.html"},{"id": "0bbc1f1f13121586804bb72e245448b2","ctime": "2023-07-06 20:26","title": "中国电信研究院副院长李安民:发展元宇宙,要提","description": "","source": "网易科技","picUrl": "https://nimg.ws.126.net/?url=http%3A%2F%2Fbjnewsrec-cv.ws.126.net%2Flittle64910ee1b6bj00rxctez005jd000j600anp.jpg&thumbnail=200y140&quality=100&type=jpg","url": "https://www.163.com/dy/article/I9071U0D0519DFFO.html"},{"id": "1962b01db3569398109fe336d5f8ff29","ctime": "2023-07-06 20:42","title": "XR“失宠”?头显出货量下降超三成,元宇宙再降","description": "","source": "网易科技","picUrl": "https://nimg.ws.126.net/?url=http%3A%2F%2Fbjnewsrec-cv.ws.126.net%2Flittle252508775e3j00rxdev60080c000se00fsg.jpg&thumbnail=200y140&quality=100&type=jpg","url": "https://www.163.com/dy/article/I907V12305199NPP.html"}]}
}

App客户端

MVP规范接口:IView、IModel、IPresenter,用于规范接口

package com.xzln.eatwhatjava.view;public interface IView {}  // 用于规范View层接口
package com.xzln.eatwhatjava.model;public interface IModel {}  // 用于规范Model层接口
package com.xzln.eatwhatjava.presenter;import com.xzln.eatwhatjava.view.IView;/*** 抽离公共接口*      所有的P层对象都公有* 	    而V层和M层对象则都是根据具体的业务进行定制* @param <V>*/
public interface IPresenter<V extends IView> {/*** 依附生命view* @param view v层对象*/void attachView(V view);/*** 分离View*/void detachView();/*** 判断View是否已经销毁* @return 是否销毁*/boolean isViewAttached();
}

回调规范接口:ICallBack

package com.xzln.eatwhatjava.contact;public interface ICallBack<T, K> {void onSuccess(T data);void onFail(K data);
}

布局逻辑

ViewPager2+Fragment

其中Fragment由refreshLayout+RecycleView组成,RecycleView放新闻条目。

ViewPager2用于对新闻进行分类

主界面布局
// activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".view.MainActivity"android:orientation="vertical"><com.google.android.material.tabs.TabLayoutandroid:id="@+id/tab_layout"android:layout_width="match_parent"android:layout_height="40dp"android:background="@color/colorPrimary"app:tabGravity="fill"app:tabMode="fixed"app:tabTextColor="@android:color/white" /><androidx.viewpager2.widget.ViewPager2android:id="@+id/view_pager2"android:layout_width="match_parent"android:layout_height="match_parent" />
</LinearLayout>
image-20230707135501986

M(Model)

// INewsModel.java
package com.xzln.eatwhatjava.model;import com.xzln.eatwhatjava.contact.ICallBack;/*** 定义规范接口:(新闻)*      单一接口的M层*/
public interface INewsModel extends IModel {// post请求void getData(int page, int num, final ICallBack callback);
}
// NewsModel.java
package com.xzln.eatwhatjava.model;import android.util.Log;import com.xzln.eatwhatjava.api.NewsApi;
import com.xzln.eatwhatjava.bean.NewsListBean;
import com.xzln.eatwhatjava.bean.Result;
import com.xzln.eatwhatjava.config.NewsConfig;
import com.xzln.eatwhatjava.contact.ICallBack;
import com.xzln.eatwhatjava.utils.RetrofitUtils;import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
/*** 定义了News功能模块的M层类*       调用retrofit网络API,通过CallBack将数据传到P层* TODO: onNext中发生错误的情况 和 onError中发生错误的情况 都有哪些*/
public class NewsModel implements INewsModel {public static final String TAG = "com.xzln.eatwhatjava.model.NewsModel";@Overridepublic void getData(int page, int num, ICallBack callback) {fetchKejiNews(page, num).observeOn(AndroidSchedulers.mainThread())  // Android 主线程观察.subscribeOn(Schedulers.io())   // 消费.subscribe(new Observer<Result<NewsListBean>>() { // URL访问成功@Overridepublic void onSubscribe(Disposable d) {}@Overridepublic void onNext(Result<NewsListBean> newsListBeanResult) {  // 数据迭代器?if (null == newsListBeanResult) { callback.onFail("出现错误: null == newsListBeanResult"); } else if (newsListBeanResult.getCode() != 200) { callback.onFail(newsListBeanResult.getMsg());} else { callback.onSuccess(newsListBeanResult); }}@Overridepublic void onError(Throwable e) {  // 访问错误或者数据解析错误e.printStackTrace();callback.onFail("出现错误: onError");}@Overridepublic void onComplete() { Log.d(TAG, "onComplete"); }});}protected Observable<Result<NewsListBean>> fetchKejiNews(int page, int num) {return RetrofitUtils.getRetrofit().create(NewsApi.class).fetchKejiNews(NewsConfig.getKejiNewsFieldMap(page, num));}
}

V(View)

// INewsView.java
package com.xzln.eatwhatjava.view;import com.xzln.eatwhatjava.presenter.IPresenter;/*** 定义News功能模块的View类的规范接口*      (P层和V层的桥梁)* @param <P> P层对象类型* @param <T> P层访问成功时返回的类型* @param <V> P层访问失败时返回的类型*/
public interface INewsView<P extends IPresenter, T, V> extends IView{void showNewsSuccess(T newsBeans);void showNewsFail(V data);
}
package com.xzln.eatwhatjava.base;import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import com.xzln.eatwhatjava.presenter.IPresenter;
import com.xzln.eatwhatjava.view.IView;/*** 抽象类,Fragment的公共抽象类* @param <P>*/
public abstract class BaseFragment<P extends IPresenter> extends Fragment implements IView {protected P mPresenter;  // P层对象,用于和V层、M层进行联系protected View mView;  // V层对象,通过V层对象完成P和V之间的联系/*** 完成P层对象的创建和初始化* @param savedInstanceState If the fragment is being re-created from* a previous saved state, this is the state.*/@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);initPresenter();init();}/**** @param inflater The LayoutInflater object that can be used to inflate* any views in the fragment,* @param container If non-null, this is the parent view that the fragment's* UI should be attached to.  The fragment should not add the view itself,* but this can be used to generate the LayoutParams of the view.* @param savedInstanceState If non-null, this fragment is being re-constructed* from a previous saved state as given here.** @return 视图对象*/@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// Inflate the layout for this fragmentmView = inflater.inflate(getLayoutId(), container, false);return mView;}/*** Fragment销毁时,先取消P层对象和Fragment的绑定,避免空指针异常*/@Overridepublic void onDestroy() {if (mPresenter != null && mPresenter.isViewAttached()) {mPresenter.detachView();}super.onDestroy();}/*** 创建和初始化P层对象,将P层对象生命周期与当前Fragment绑定*/protected void initPresenter() {mPresenter = createPresenter();//绑定生命周期if (mPresenter != null) {mPresenter.attachView(this);}}/*** 抽象方法,由子类根据对应的布局来实现,返回其布局ID,用于Fragment的OnCreateView* @return 布局ID*/public abstract int getLayoutId();/*** 创建一个Presenter** @return P层对象*/protected abstract P createPresenter();/*** 用于子类的其他数据的初始化*/protected abstract void init();}
//NewsFragment.java
package com.xzln.eatwhatjava.view;import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;import com.xzln.eatwhatjava.R;
import com.xzln.eatwhatjava.adapter.NewsRecycleViewAdapter;
import com.xzln.eatwhatjava.base.BaseFragment;
import com.xzln.eatwhatjava.bean.NewsBean;
import com.xzln.eatwhatjava.presenter.NewsPresenter;import java.util.LinkedList;
import java.util.List;/*** News的布局碎片*/
public class NewsFragment extends BaseFragment<NewsPresenter> implements INewsView<NewsPresenter, List<NewsBean>, String> {private static final String TAG = "com.xzln.eatwhatjava.view.NewsFragment";protected int mNewsType;  // News的类别,由创建者传入protected SwipeRefreshLayout mSwipeRefreshLayout;  // 顶部的刷新布局protected RecyclerView mRecycleView;protected List<NewsBean> mNewsBeans;  // 数据列表protected int mCurPage = 0;  // 当前页码protected int mNumOfPage = 25;  // 每页中数据数目protected NewsRecycleViewAdapter mNewsRecycleViewAdapter;  // RecycleView适配器protected LinearLayoutManager mLinearLayoutManager;private int mTotalItemCount;/*recycleView下的总item数目*/private int mFirstVisibleItem;/*当前可见区内最后一个item的position*/private int mLastVisibleItem;/*当前可见区内最后一个item的position*//*Return the current number of child views attached to the parent RecyclerView.*/private int mVisibleItemCount;/*当前recycleView下可见的item数*/public NewsFragment(int newsType) {  mNewsType = newsType; }/*** 刷新时调用:页码清零、数据清空、重新获取数据*/protected void refreshView() {mCurPage = 0;mNewsBeans.clear();mNewsRecycleViewAdapter.clearData();mPresenter.getNewsData(mCurPage++, mNumOfPage);}@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return super.onCreateView(inflater, container, savedInstanceState);}@Overridepublic void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);mSwipeRefreshLayout = mView.findViewById(R.id.layout_swipe_refresh);mRecycleView = mView.findViewById(R.id.view_recycle);// mPresenter.getNewsData(mCurPage++, mNumOfPage);refreshView();setupListener();}/*** 用于创建P层对象,由子类具体定制实现* @return P层对象*/@Overrideprotected NewsPresenter<NewsFragment> createPresenter() { return new NewsPresenter<>(this); }/*** 由子类定制,用于完成子类中的数据初始化*  视图id的绑定不可在这完成。因为视图View对象的生成在OnCreateView,而init函数在OnCreate中*/@Overrideprotected void init() {mNewsBeans = new LinkedList<>();mNewsRecycleViewAdapter = new NewsRecycleViewAdapter(getActivity(), mNewsBeans);}/*** @return 视图布局文件的ID*/@Overridepublic int getLayoutId() { return R.layout.activity_fragment_main; }/*** 启动监听器* 1. 刷新头* 2. RecycleView适配器、布局管理器*/private void setupListener() {mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {@Overridepublic void onRefresh() {Log.d(TAG, "mSwipeRefreshLayout.setOnRefreshListener.onRefresh");
//                mSwipeRefreshLayout.setRefreshing(false);refreshView();new Handler().postDelayed(new Runnable() {@Overridepublic void run() { mSwipeRefreshLayout.setRefreshing(false); }},2000);}});mLinearLayoutManager = new LinearLayoutManager(getActivity());mRecycleView.setLayoutManager(mLinearLayoutManager);mRecycleView.setAdapter(mNewsRecycleViewAdapter);/*recycleView*/mRecycleView.addOnScrollListener(new RecyclerView.OnScrollListener() {@Overridepublic void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {super.onScrollStateChanged(recyclerView, newState);Log.d(TAG, "onScrollStateChanged  -->  newState" + newState);// 获取数据逻辑// 滚动状态改变 && 最后一个position + 1 >= totalif (newState == RecyclerView.SCROLL_STATE_DRAGGING &&mLastVisibleItem + 1 >= mTotalItemCount &&mVisibleItemCount <= mTotalItemCount) {mPresenter.getNewsData(mCurPage++, mNumOfPage);}@Overridepublic void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {super.onScrolled(recyclerView, dx, dy);mLinearLayoutManager.findFirstVisibleItemPosition();mTotalItemCount = mLinearLayoutManager.getItemCount();mFirstVisibleItem = mLinearLayoutManager.findFirstVisibleItemPosition();mLastVisibleItem = mLinearLayoutManager.findLastVisibleItemPosition();/*当前可见区内最后一个item的position*//*Return the current number of child views attached to the parent RecyclerView.*/mVisibleItemCount = mLinearLayoutManager.getChildCount();/*当前recycleView下可见的item数*/}});}/*** 与P层联系的函数* @param newsBeans P层成功返回的数据*/@Overridepublic void showNewsSuccess(List<NewsBean> newsBeans) {Log.d(TAG, "showNewsSuccess  newsBeans.size()=" + newsBeans.size());mNewsRecycleViewAdapter.addData(newsBeans);}/*** 与P层联系的函数* @param data P层失败返回的数据*/@Overridepublic void showNewsFail(String data) {Log.d(TAG, "showNewsSuccess");}
}

P(Presenter)

// IPresenter.java
package com.xzln.eatwhatjava.presenter;import com.xzln.eatwhatjava.view.IView;/*** 抽离公共接口*      所有的P层对象都公有* @param <V>*/
public interface IPresenter<V extends IView> {/*** 依附生命view* @param view v层对象*/void attachView(V view);/*** 分离View*/void detachView();/*** 判断View是否已经销毁* @return 是否销毁*/boolean isViewAttached();
}
// BasePresenter.java
package com.xzln.eatwhatjava.base;import com.xzln.eatwhatjava.presenter.IPresenter;
import com.xzln.eatwhatjava.view.IView;/*** IPresenter接口需要所有的P层实现类继承* 对于生命周期这部分功能P层都是通用的,因此可以抽出来一个抽象基类BasePresenter,去实现IPresenter的接口.* @param <V>*/
public abstract class BasePresenter<V extends IView> implements IPresenter<V> {protected V mView;@Overridepublic void attachView(V view) { mView = view; }@Overridepublic void detachView() { mView = null; }@Overridepublic boolean isViewAttached() { return mView != null; }
}

P层对象中持有V层对象和M层对象
P层调用M层获取数据,并设置CallBack。通过CallBack完成M层和P层间的联系。
在CallBack中调用View对象,完成P层与V层的联系。

// NewsPresenter.java
package com.xzln.eatwhatjava.presenter;import android.util.Log;import com.xzln.eatwhatjava.base.BasePresenter;
import com.xzln.eatwhatjava.bean.NewsListBean;
import com.xzln.eatwhatjava.bean.Result;
import com.xzln.eatwhatjava.contact.ICallBack;
import com.xzln.eatwhatjava.model.INewsModel;
import com.xzln.eatwhatjava.model.NewsModel;
import com.xzln.eatwhatjava.view.INewsView;
import com.xzln.eatwhatjava.view.IView;/*** News功能模块P层逻辑* @param <V>*/
public class NewsPresenter<V extends IView> extends BasePresenter<V> {private static final String TAG = "com.xzln.eatwhatjava.presenter.NewsPresenter";protected INewsView mNewsView;protected INewsModel mNewsModel;public NewsPresenter(V view) {mNewsView = (INewsView) view;createModel();}private void createModel() {if (mNewsModel == null) { mNewsModel = new NewsModel(); }}public void getNewsData(int page, int num) {mNewsModel.getData(page, num,new ICallBack<Result<NewsListBean>, String>() {  // P层定义CallBack,从而将数据从@Overridepublic void onSuccess(Result<NewsListBean> data) {Log.d(TAG, ".getData.onSuccess");mNewsView.showNewsSuccess(data.getResult().getNewslist());}@Overridepublic void onFail(String data) {mNewsView.showNewsFail("数据获取失败");Log.d(TAG, ".getData.onFail -->  " + data);}});}
}
// ICallBack.java
package com.xzln.eatwhatjava.contact;public interface ICallBack<T, K> {void onSuccess(T data);void onFail(K data);
}

Okhttp+Retrofit+RxJava网络http请求

RetrofitUtil

//RetrofitUtils.java
package com.xzln.eatwhatjava.utils;import com.xzln.eatwhatjava.config.NewsConfig;import java.util.concurrent.TimeUnit;import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;public class RetrofitUtils {private static Retrofit retrofit;private static OkHttpClient okhttp;/*** 自定义okhttp客户端** @return okhttp客户端*/public static OkHttpClient getOkhttp() {if (okhttp == null) {synchronized (RetrofitUtils.class) {if (okhttp == null) {okhttp = new OkHttpClient.Builder().connectTimeout(15, TimeUnit.SECONDS).readTimeout(15, TimeUnit.SECONDS).writeTimeout(15, TimeUnit.SECONDS).build();}}}return okhttp;}/*** 单例retrofit客户端** @return retrofit客户端*/public static Retrofit getRetrofit() {if (retrofit == null) {synchronized (RetrofitUtils.class) {if (retrofit == null) {retrofit = new Retrofit.Builder().baseUrl(NewsConfig.newsBaseUrl).addCallAdapterFactory(RxJava2CallAdapterFactory.create()).addConverterFactory(GsonConverterFactory.create()).client(getOkhttp()).build();}}}return retrofit;}
}
//NewsApi.java
package com.xzln.eatwhatjava.api;import com.xzln.eatwhatjava.bean.NewsListBean;
import com.xzln.eatwhatjava.bean.Result;import java.util.Map;
import io.reactivex.Observable;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;public interface NewsApi {// POST请求数据@FormUrlEncoded@POST("keji/index")Observable<Result<NewsListBean>> fetchKejiNews(@FieldMap Map<String, Object> map);
//    Observable<Result<List<NewsBean>>> fetchKejiNews(@FieldMap Map<String, Object> map);
}

Mvp架构-初学者

MVP架构是为了让各个模块之间降低耦合,方便维护,也可以让代码更简洁,让代码简洁的意思是让代码更清晰,并不是让代码更少;MVP契约者是为了进一步的低耦合、接口统一管理。

image.png

MVP对接口灵活的调用可以轻松的应对产品的变更。

presenter 类与View 和 Model 通信,做到视图和逻辑的解耦。

MVP架构的契约者

TODO

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

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

相关文章

flink1.18.0 自适应调度器 资源弹性缩放 flink帮你决定并行度

jobmanager.scheduler Elastic Scaling | Apache Flink 配置文件修改并重启flink后,webui上会显示调整并行度的按钮,他可以自己调整,你也可以通过webUI手动调整: 点击 之后: 调整完成后:

机器学习——朴素贝叶斯

目录 一、贝叶斯方法 背景知识 贝叶斯公式 二、朴素贝叶斯原理 判别模型和生成模型 1&#xff0e;朴素贝叶斯法是典型的生成学习方法 2&#xff0e;朴素贝叶斯法的基本假设是条件独立性 3&#xff0e;朴素贝叶斯法利用贝叶斯定理与学到的联合概率模型进行分类预测 用于文…

FindMy网络帮助您找到电动车

随着科技的发展&#xff0c;我们的生活变得越来越智能化。而现在&#xff0c;这项技术已经深入到了我们的出行方式中。如果你是一位电动车主&#xff0c;那么你可能会遇到一个常见的问题&#xff1a;忘记你的电动车停在了哪里。这种情况在日常生活中时有发生&#xff0c;而现在…

Python - 利用 OCR 技术提取视频台词、字幕

目录 一.引言 二.视频处理 1.视频样式 2.视频截取 ◆ 裁切降帧 ◆ 处理效果 3.视频分段 三.OCR 处理 1.视频帧处理 2.文本识别结果 3.后续工作与优化 ◆ 识别去重 ◆ 多线程提效 ◆ 片头片尾优化 四.总结 一.引言 视频经常会配套对应的台词或者字幕&#xff0c…

CSS时间线样式

css实现时间线样式&#xff0c;效果如下图&#xff1a; 一、CSS代码 .timeline {padding-left: 5px} .timeline-item { position: relative;padding-bottom: 20px;} .timeline-axis {position: absolute;left: -5px;top: 0;z-index: 10;width: 20px;height: 20px;line-he…

火爆全网!用 Pyecharts 就能做出来“迁徙图“和“轮播图“

1.pyecharts知识点回顾 1&#xff09;知识回顾 前面我们已经讲述了&#xff0c;如何使用pyecharts进行图形的绘制&#xff0c;一共涉及到如下四步。我们今天就是按照下面这几步来进行迁徙图和轮播图的绘制。 ① 选择图表类型&#xff1b; ② 声明图形类并添加数据&#xff1…

uni-app基于vite和vue3创建并集成pinia实现数据持久化

一、uni-app基于Vite和Vue3创建并集成pinia实现数据持久化 文章目录 一、uni-app基于Vite和Vue3创建并集成pinia实现数据持久化1.如何创建基于Vite和Vue3的uni-app项目&#xff1f;2.选择其中一个分支&#xff0c;就是一个脚手架 二、以下都是基于vite-ts版本创建和配置1.目录结…

用友NC Cloud accept.jsp接口任意文件上传漏洞复现 [附POC]

文章目录 用友NC Cloud accept.jsp接口任意文件上传漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 用友NC Cloud accept.jsp接口任意文件上传漏洞复现 [附POC] 0x01 前言 免责声明&#xff1a…

Redis客户端-引入jedis

ssh端口转发 Redis服务器在官网公开了使用的协议(RESP),此时任何一个第三方都可以通过上述协议,来实现出一个和redis服务器通信的客户端程序. 现在,已经有很多库可以让我们直接调用,就不必关注redis协议的细节了. 在java的生态中,封装了RESP协议,实现的redis客户端有很多,我…

JavaScript脚本操作CSS

脚本化CSS就是使用JavaScript脚本操作CSS&#xff0c;配合HTML5、Ajax、jQuery等技术&#xff0c;可以设计出细腻、逼真的页面特效和交互行为&#xff0c;提升用户体验&#xff0c;如网页对象的显示/隐藏、定位、变形、运动等动态样式。 1、CSS脚本化基础 CSS样式有两种形式&…

[yarn]yarn异常

一、运行一下算圆周率的测试代码&#xff0c;看下报错 cd /home/data_warehouse/module/hadoop-3.1.3/share/hadoop/mapreduce hadoop jar hadoop-mapreduce-examples-3.1.3.jar pi 1000 1000 后面2个数字参数的含义&#xff1a; 第1个1000指的是要运行1000次map任务 …

【C++心愿便利店】No.12---C++之探索string底层实现

文章目录 前言一、写实拷贝&#xff08;了解&#xff09;二、string类常用接口实现2.1 成员变量2.2 默认构造函数2.3 拷贝构造函数2.4 operator2.5 operator[]2.6 c_str2.7 size()2.8 capacity() 三、迭代器的实现3.1 begin()和end()3.2 范围for 四、string类增删查改4.1 reser…

偶数科技携Skylab实时湖仓数据平台亮相2023全国中小企业数字化转型大会

2023全国中小企业数字化转型大会于10月28日至30日在安徽省合肥市举行&#xff0c;本次大会以“数实融合 赋能万企”为主题&#xff0c;由工业和信息化部、安徽省人民政府主办。会议期间&#xff0c;偶数科技等典型企业的数字化转型新技术、新产品、新应用、新模式集聚亮相&…

【Git】安装和常用命令的使用与讲解及项目搭建和团队开发的出现的问题并且给予解决

目录 Git的简介 介绍 Git的特点及概念 Git与SVN的区别 图解 ​编辑 命令使用 安装 使用前准备 搭建项目环境 ​编辑 团队开发 Git的简介 介绍 Git 是一种分布式版本控制系统&#xff0c;是由 Linux 之父 Linus Torvalds 于2005年创建的。Git 的设计目标是为了更好地管…

【LeetCode: 54. 螺旋矩阵 | 模拟】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

react 修改less文件后保存,内存溢出,项目崩溃问题解决

一、完整报错 一个很老的react项目&#xff0c;因为没有package-lock.json版本锁&#xff0c;导致拉下来的时候&#xff0c;安装的依赖版本冲突&#xff0c;好不容易启动起来&#xff0c;修改less文件后只要一保存&#xff0c;项目就会崩溃&#xff0c;需要重启&#xff0c;报…

【uni-app + uView】CountryCodePicker 国家区号组件

1. 效果图 2. 组件完整代码 <template><u-popup class="country-code-picker-container" v-if="show" :show

2013年108计网

第33题 在 OSI 参考模型中, 下列功能需由应用层的相邻层实现的是()A. 对话管理B. 数据格式转换C. 路由选择D. 可靠数据传输 很显然&#xff0c;题目所问的应用层的相邻层是表示层。该层实现与数据表示相关的功能。选项a中的对话管理属于会话层。选项c中的路由选择属于网络层。…

机器学习 - 决策树:技术全解与案例实战

目录 一、引言二、决策树基础决策树模型概述构建决策树的关键概念特征选择决策树的生成 决策树的剪枝 三、算法研究进阶提升树和随机森林提升树&#xff08;Boosted Trees&#xff09;随机森林&#xff08;Random Forests&#xff09; 进化算法与决策树决策树结构的进化 多目标…

吃啥大转盘

经常跟朋友出去吃饭&#xff0c;选择太困难了所以写了个简单的转盘&#xff0c;直接copy到txt文本然后把文件后缀改成html即可。 需要换食物直接在文件中找到 list 值按照格式替换一下即可。 效果&#xff1a; 代码块&#xff1a; <html><head><meta http-…