android 基础

    <TextView
<!--        宽度根据父级设置-->
        android:layout_width="match_parent"  
        android:layout_height="match_parent"/>
    <TextView
<!--        根据里面内容自动计算宽高-->
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

  android:textColor="#2000FF00"

设置颜色 RGB 每两位一组 顺序是 红绿蓝
FF0000 就是红色
想要半透明 #50FF0000 这么设置

可以设置图片 也可以设置图片
android:background="#fff0000"
设置居中
android:gravity="center"

阴影设置

android:shadowColor="@color/black" 颜色
       android:shadowRadius="0.1" 模糊度
       android:shadowDx="20" 偏移

跑马灯

       android:singleLine="true"  文字不换行
        android:ellipsize="marquee"  边界省略
        android:marqueeRepeatLimit="marquee_forever" 滚动次数
        android:focusable="true" Android TextView 是否可以获得焦点
        android:focusableInTouchMode="true" Android TextView 是否可以在触摸模式下获取焦点

进入页面直接开始滚动
在双标签中加入


image.png

Button

根据不同样式设置不同效果

image.png

单击按钮的样式变化 按下一个显示 松开一个显示
使用drawable 下面新建一个rescource资源
1
image.png

2
在资源下新建item项 并设置两种样式 一种单击下的图片 一种不点击的样式
(要设置为图片)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/baseline_accessible_24" android:state_pressed="true"/>  //点击变成这个 
    <item android:drawable="@drawable/baseline_accessible_forward_24"/>

</selector>

还可以设置颜色选择器 比如按下红色 默认黑色

  • 1 在res新建一个color文件夹
  • 2 创建rescource文件 item项目
    android:backgroundTint="@color/btn_color_change"

进行单击改变颜色的切换
Button 事件处理
三种时间
1单击事件
2 长按事件
3 触摸事件

    Button btn = findViewById(R.id.btn);
        //点击事件
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //
            }
        });
        //长按事件
        btn.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                return false;
            }
        });
        // 触摸时间
        btn.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                return false;
            }
        });

当return 为true时,其他的方法不会再被调用了

编辑框 EditText

主要属性

image.png

ImageView

image.png

processBar 进度条

进度条

Notification与NotificationManger

通知管理类,单例方式模式

import android.app.NotificationManager;
import android.content.Context;
import android.support.v4.app.NotificationCompat;

public class MyNotificationManager {

    private static final int NOTIFICATION_ID = 1;
    private static final String CHANNEL_ID = "my_channel_01";
    private static final CharSequence CHANNEL_NAME = "My Channel";

    // 显示通知的方法
    public static void showNotification(Context context, String title, String message) {
        // 获取 NotificationManager 实例
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        // 使用 NotificationCompat.Builder 创建通知对象
        NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
                .setSmallIcon(R.drawable.notification_icon) // 设置通知小图标
                .setContentTitle(title) // 设置通知标题
                .setContentText(message) // 设置通知内容
                .setPriority(NotificationCompat.PRIORITY_DEFAULT); // 设置通知优先级

        // 发送通知
        notificationManager.notify(NOTIFICATION_ID, builder.build());
    }

    // 取消通知的方法
    public static void cancelNotification(Context context) {
        // 获取 NotificationManager 实例
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        
        // 取消指定 ID 的通知
        notificationManager.cancel(NOTIFICATION_ID);
    }
}
image.png

toolBar 最上方导航栏

image.png
image.png
image.png

如何让标题处于居中位置呢 ?
将toolbar设置为双标签,然后将textView文本放在中间 写上layout_gravity="center" 就居中了

居中

AlertDialog

image.png

image.png

LinearLayout

纵向排列

   <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:background="#00ff00"
       android:orientation="vertical" 纵向布局
       >
       <LinearLayout
           android:layout_width="50dp"
           android:layout_height="50dp"
           android:background="#00fff0"
           ></LinearLayout>

       <LinearLayout
           android:layout_width="50dp"
           android:layout_height="50dp"
           android:background="#f0ffff"
           ></LinearLayout>

       <LinearLayout
           android:layout_width="50dp"
           android:layout_height="50dp"
           android:background="#ff00ff"
           ></LinearLayout>

   </LinearLayout>

image.png

android:gravity="center" 让其所有子元素布局方式
也可以加或语句进行复式用法 比如说居中又在底部
android:gravity="center | bottom"

image.png

分割线

       android:divider="@drawable/baseline_arrow_back_ios_24"  边框线
       android:showDividers="middle"  粗度
       android:dividerPadding="100dp"  边距


分割线
 <LinearLayout
           android:layout_width="50dp"
           android:layout_height="50dp"
           android:background="#00fff0"
           android:layout_weight="1" 权重进行空间分配(在原有的基础上)
           ></LinearLayout>

RelativeLayout

image.png

兄弟组件根据id来进行放置
写法为android:layout_toRightOf="@id/l2"

margin 距离父元素距离 padding 距离内容距离

FrameLayout 帧布局

从左上角开始绘制

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <FrameLayout
        android:layout_width="400dp"
        android:layout_height="400dp"
        android:background="#ff0000">

    </FrameLayout>

    <FrameLayout
        android:layout_width="300dp"
        android:layout_height="400dp"
        android:background="#fff000">

    </FrameLayout>

</FrameLayout>

![image.png](https://upload-images.jianshu.io/upload_images/24559446-f7d01a2b6823dea0.png? imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

        android:foreground="@drawable/btn_one" 设置前景色
        android:foregroundGravity="right" 设置前景色位置

TableLayout 表格布局

默认独占一行

<TableLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
        <Button
            android:text="按钮"
            
            >

        </Button>



</TableLayout>
image.png

要放在tableRow中


<TableLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <TableRow>
        <Button android:text="按钮"/>
        <Button android:text="按钮2"/>
    </TableRow>

</TableLayout>
image.png

隐藏列
在tableLayout中使用属性android:collapseColumns="0"
0表示隐藏第一列 0,2 隐藏第1列和第3列

拉伸列
android:stretchColumns="0" 拉伸第一列的,铺满剩余空间。

收缩列
有超出部分不显示,可以设某一个列收缩
android:shrinkColumns="0"

子控件设置


image.png

GridLayout


<GridLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnCount="3" 一行最多显示3列 
    >
        <Button/>
        <Button/>
        <Button/>
        <Button/>
        <Button/>


</GridLayout>
image.png

子控件属性


image.png

ConstrainLayout 约束布局

image.png

在这上面拖动

ListView

ListView 是 Android 中常用的一个列表视图控件,用于在界面上展示一系列的数据项。它可以用来显示垂直滚动的列表,每个列表项都可以包含一个自定义的布局。

要在布局文件中添加一个 ListView 控件,可以使用以下 XML 代码:

xml
Copy code
<ListView
    android:id="@+id/listView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

在代码中,您可以通过调用 findViewById() 方法来获取对 ListView 控件的引用,然后为其设置适配器,以便显示数据。

java
Copy code
ListView listView = findViewById(R.id.listView);

// 创建一个适配器并设置给ListView
ListAdapt adapter = new ListAdapt(dataList, context);
listView.setAdapter(adapter);
在上面的示例中,dataList 是要显示的数据列表,context 是当前的上下文对象。ListAdapt 是您自定义的适配器,用于将数据绑定到 ListView 上。

最后,您可以设置 ListView 的点击事件监听器,以便在用户点击列表项时执行相应的操作。

java
Copy code
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
        // 处理点击事件,position 是被点击的列表项的位置
    }
});

通过以上步骤,您就可以在 Android 应用程序中使用 ListView 控件来展示数据了。

RecyclerView

首先引入相关依赖
implementation 'androidx.recyclerview:recyclerview:1.1.0'
使用 RecyclerView 时,您需要执行以下步骤:

  1. 在布局文件中添加 RecyclerView 控件: 在您的布局文件(通常是 XML 文件)中添加一个 RecyclerView 控件,用于显示列表或网格数据。您可以使用以下代码示例添加一个 RecyclerView:
<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
  1. 创建列表项布局文件: 创建一个布局文件,用于定义 RecyclerView 中每个列表项的外观。例如,您可以创建一个名为 list_item.xml 的布局文件。

  2. 创建 RecyclerView 适配器: 创建一个适配器类,继承自 RecyclerView.Adapter,并实现必要的方法。适配器负责将数据绑定到 RecyclerView 上。

  3. 配置 RecyclerView 的布局管理器: 在代码中配置 RecyclerView 的布局管理器,以确定列表项是线性排列还是网格排列等。

  4. 设置适配器: 获取对 RecyclerView 控件的引用,并将适配器设置给它。

  5. 准备数据: 准备要在 RecyclerView 中显示的数据。这可能是一个列表或数组,其中包含您要显示的数据项。

以下是一个简单的示例,演示了如何在 Android 应用程序中使用 RecyclerView:

public class MainActivity extends AppCompatActivity {
    private RecyclerView recyclerView;
    private List<String> data = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 准备数据
        data.add("Item 1");
        data.add("Item 2");
        data.add("Item 3");
        data.add("Item 4");
        data.add("Item 5");

        // 获取对 RecyclerView 控件的引用
        recyclerView = findViewById(R.id.recyclerView);

        // 创建一个布局管理器并设置给 RecyclerView
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        // 创建一个适配器并设置给 RecyclerView
        MyAdapter adapter = new MyAdapter(data);
        recyclerView.setAdapter(adapter);
    }
}

在这个示例中,我们使用了 RecyclerView 和 LinearLayoutManager。接下来,您需要创建适配器类 MyAdapter,并实现必要的方法,例如 onCreateViewHolder()onBindViewHolder()getItemCount()。以下是适配器类的示例:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private List<String> data;

    public MyAdapter(List<String> data) {
        this.data = data;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        String item = data.get(position);
        holder.textView.setText(item);
    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        TextView textView;

        public ViewHolder(View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.textView);
        }
    }
}

在这个示例中,我们创建了一个简单的适配器类 MyAdapter,用于将数据绑定到 RecyclerView 上。我们还定义了一个内部 ViewHolder 类,用于保存每个列表项的视图。在 onBindViewHolder() 方法中,我们将数据绑定到 ViewHolder 中的视图上。

最后,您还需要创建列表项的布局文件 list_item.xml,用于定义每个列表项的外观。

动画

1 帧动画
几张图片进行快速播放
首先在drable创需一个xml文件


image.png

用的时候直接放在视图容器就OK


image.png

单位和尺寸

px像素 不同设备显示效果不同
因为每个屏幕的像素点不一样 如像素点多的手机 你设置10px很小

dip 设备独立像素 适配不同屏幕大小的单位

dp :随着屏幕的大小变化

sp 用于字体 scaled pixels (放大像素)

ViewPager 视图翻页器

下次学

MVVM

image.png

Fragment

可重用的界面组件的类。它代表了一个可嵌入到活动中的独立的用户界面部分,可以包含自己的布局、生命周期和行为。与活动(Activity)不同,Fragment 可以在同一个屏幕上同时存在多个,并且可以灵活地在不同的屏幕配置(如手机和平板电脑)中重用。

他是什么?
相当于vue中的框架

比如在同一页面中,左侧为列表,右侧为单击列表所显示的内容

相当于ipad中的布局


framement

1.具备声明周期 相当于子activity
2.必须委托在activity中才能运行

activity生命周期结束 ,fragment结束.

然后在layout中创建fragment文件,在java中也创建一个framement_acticity来获取到layout的组件进行控制,然后返回

如何绑定到activity中呢
Fragmen_blank.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".BlankFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:id="@+id/textView"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:text="@string/hello_blank_fragment" />
    <Button
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:id="@+id/tbn"
        android:text="点击"/>

</LinearLayout>

Fragmen_blank.java

package com.lifang.project;

import android.os.Bundle;

import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link BlankFragment#    } factory method to
 * create an instance of this fragment.
 */
public class BlankFragment extends Fragment {
    private View root;
    private TextView textView;
    private Button button;

    // TODO: Rename and change types and number of parameters


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        if (root == null) {
            root = inflater.inflate(R.layout.fragment_blank,container,false);

        }
        textView = root.findViewById(R.id.textView);
        button = root.findViewById(R.id.tbn);
//        btn 点击 修改文本内容
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText("变成新内容");
            }
        });

        // Inflate the layout for this fragment
        return root;
    }
}

绑定在activity页面中进入小写的标签fragment 去引用

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:orientation="vertical"
    >

<fragment
    android:id="@+id/framgment" //使用必须有id
    android:name="com.lifang.project.BlankFragment"//framgment创建位置
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

</LinearLayout>

就是一个小型的activity.`

动态添加fragment

activity和fragment通信

使用Bundle

在mainactivity中 
Bundle bundle = new bundle();
bundle.put("message","威威"); //此行代码是往fragment传递数据
blankFragment bf = new BlankFragmenet();
bf.setArguments(bundle);

在fragment.java中

在任何地方可以使用
Bundle bundle = this.getArguments();//来进行获取acticity里面传过来的参数
bundle.getString()

动态添加fragment

创建一个待处理的fragment
获取fragmentmanager,
开启一个事务 transaction
进行替换
提交事务

类与类用接口进行通讯
IFragmentCallback

public interface IFragmentCallBack {
    //通过接口实现通讯
    //fragment给activity发送信息
    void sendMsgToActivity(String s);

    String getMsgFromActivity(String s);

}

要完成通讯,现在fragment里面定义一个callback函数

private IFragmentCallback fragmentCallback;
//activity 给他赋值
public void setFragmentCallback(IFragmentCallback callback){
fragmentCallback = callback;
}

这样很麻烦 所以使用eventBus来进行.

生命周期


image.png

ViewPage的使用

相当于微信底部导航的切换页面

image.png

image.png

要实现微信底部导航按钮跟fragment联动效果,需要使用BottomnavigationView

二,activity 组件

activity 就是页面活动的跳转,比如从第几个页面跳转到第几个页面
他有他的生命周期


image.png

所有的activity组件都要在清单文件中注册。


image.png

三,service组件

服务在后台运行,是不可见的。

创建一个类,继承Service就是服务

三,广播 Receiver

  • 系统广播
  • 自定义广播

四,热修复

当应用上线后出现bug,不需要重新安装安装包,只需要发布补丁包,让用户没有感知的情况下进行更新
项目中引入Tinker来进行热修复
Bugly+Tinker实现热修复

image.png

image.png

image.png

五,引入高德地图SDK

高德地图sdk

Glide的图片加载库使用

image.png

image.png

网络请求失败的情况


image.png

网络请求加载框架

OkHttp与Retrofit
okhttp 处理网络请求的
implementation 'com.squareup.okhttp3:okhttp:4.9.0'加入到项目中

要进行权限注册在Manifest中
<uses-permission android:name="android.permission.INTERNET"/>

image.png

同步请求

public class  MainActivity extends AppCompatActivity {
    private static final String TAG ="MainActivity";
    private OkHttpClient okHttpClient;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //创建网络请求的
      okHttpClient = new OkHttpClient();
    }

    public void get(View view) {
        //在安卓中要完成网络的请求必须有一个子线程来完成这个事情,要在线程中去完成这个同步请求的操作
        new Thread(){
            @Override
            public void run() {
                //创建request对象,交给请求工具okHttpClient
                Request request= new Request.Builder().url("https://www.httpbin.org/get?age=18&name=hx").build();//上传参数使用? 键值对的方式 比如age=18
                Call call = okHttpClient.newCall(request);// 准备好请求的call对象
                //进行同步请求
                try {
        //            得到的响应数据
                    Response response = call.execute();
                    Log.i(TAG, "get: "+response.body().string());

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();

    }

get异步请求

   public void getSync(View view) {
        //创建request对象,交给请求工具okHttpClient
        Request request= new Request.Builder().url("https://www.httpbin.org/get?age=18&name=hx").build();//上传参数使用? 键值对的方式 比如age=18
        Call call = okHttpClient.newCall(request);// 准备好请求的call对象
        //异步请求 enqueue里面自动有一个线程
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {

            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                //这里是与http响应成功 返回状态码,比如200 500 404等等200-300是成功 300-400重定向 400-500服务器错误
                if (response.isSuccessful()) {
                    //成功
                    Log.i(TAG, "getaSync: "+response.body().string());

                }
            }
        });
    }

post异步请求
需要将请求参数放到请求体里面

    public void postSync(View view) {
//        post请求参数需要放在请求体里面
        FormBody formBody = new FormBody.Builder().add("name", "cc").add("age", "22").build();
        Request request= new Request.Builder().url("https://www.httpbin.org/post").post(formBody).build();
        Call call = okHttpClient.newCall(request);// 准备好请求的call对象

        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {

            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                Log.i(TAG, "postaSync: "+response.body().string());
            }
        });

    }

其实就是封装了OkHttp,一个用来处理网络请求的开源项目.

一,首先根据http接口来创建Java接口


image.png

二,创建Retrofit对象,并生成接口实现类对象


image.png

三,接口实现类对象调用对应方法获得相应

  retrofit2.Call<ResponseBody>call = httpbinService.post("hx", "123456");
        call.enqueue(new retrofit2.Callback<ResponseBody>() {
            @Override
            public void onResponse(retrofit2.Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
                try {
                    Log.i(TAG, "postaSync: "+response.body().string());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

            @Override
            public void onFailure(retrofit2.Call<ResponseBody> call, Throwable t) {

            }
        });

Retrofit注解分类

image.png

Retrifit转换器

在接到服务器的响应数据后,目前无论是okhttp还是retrofit都只能接收到String字符串类型数据,实际开发要对字符串进行解析变成java Bean对象,或者将java对象转换为json。使其进行相互转换。

我们拿到服务器给我们传过来的json响应数据,为了方便好拿数据,所以我们需要将json数据转换为为java bean对象的格式,你们就要创建出对应的java bean类.

1 引入自动转换依赖
implementation("com.squareup.retrofit2:converter-gson:2.9.0")

** 2 **

  public void LoginTest() throws IOException {


        Call<ResponseBody> call = wanAndroidService.login("houx", "123456");
        Response<ResponseBody> response = call.execute();
        String result = response.body().string();
        System.out.println(result);

        //需要创建对应的java bean 类
        BaseResponse baseResponse = new Gson().fromJson(result, BaseResponse.class);
        System.out.println(baseResponse);

    }

Retrifit适配器

在开发中,有很多请求会出现请求嵌套的.这样会出现回调地狱的情况,比如说我要请求收藏之前必须先登录


image.png

先请求A接口,再请求B接口.

可以使用RXjava来解决这个嵌套问题
1 引入依赖
implementation("com.squareup.retrofit2:adapter-rxjava3:2.9.0")
2

   @Test
    public void rxJavaTest() {

        wanAndroidService3.login2("cc", "8483275876")
                .flatMap(new Function<BaseResponse, Publisher<?>>() {
                    @Override
                    public Publisher<?> apply(BaseResponse baseResponse) throws Throwable {
                        return wanAndroidService3.getArticle(5);
                    }
                })
                .observeOn(Schedulers.io())//网络请求在一个单独的线程 io线程
                .subscribeOn(Schedulers.newThread())//回调 切换到安卓主线程
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Throwable {
                        
                    }
                });
    }
image.png

这里的bean类不用自己一个一个写上去,可以借助BeJson工具,将json数据转换为Java Bean的格式.


image.png

使用转换器,那么就不需要自己去进行这个序列化和反序列的操作了。

post请求方式


image.png

拦截器

image.png

分别在拦截的前面执行或者拦截后执行

public class intercptor {
    @Test
    public void inter(){
        OkHttpClient okHttpClient = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
            @Override
            public Response intercept(@NonNull Chain chain) throws IOException {
                //这是请求先走拦截器 还没有发送给服务器 在这里进行处理 所有请求都添加的信息
                Request request = chain.request().newBuilder().addHeader("os","android").build();
                //前置处理
                Response response = chain.proceed(request);//
                //后置处理 在response之前
                return response;
            }
        }).addNetworkInterceptor(new Interceptor() {
            @NonNull
            @Override
            public Response intercept(@NonNull Chain chain) throws IOException {
                return null;
            }
        }).build();

        //创建request对象,交给请求工具okHttpClient
        Request request= new Request.Builder().url("https://www.httpbin.org/get?age=18&name=hx").build();//上传参数使用? 键值对的方式 比如age=18
        Call call = okHttpClient.newCall(request);// 准备好请求的call对象
        //进行同步请求
        try {
            //            得到的响应数据
            Response response = call.execute();
            System.out.println("get: "+response.body().string());

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

缓存和cookie

okhttp支持缓存,当我们第一次发送请求时,之后还发送同样的请求,可以减少和服务器的通信,从本地拿取.


image.png

Gson

是一个轻量级数据交换格式
用来java对象和json数据之间进行映射的Java类库,可以将java对象转换为json字符串

为什么要进行后端与前端的数据格式交换呢
在与前端进行数据交互时,常常需要将Java对象转换为JSON格式发送给前端,或者接收前端传递的JSON数据并转换为Java对象进行处理。

并且json数据·JSON数据相对于其他格式(如XML)来说,数据体积通常更小,传输效率更高,节省带宽和资源。·

android的依赖引用使用
implementation'com.google.code.gson:gson:2.8.6'

使用Gson实现序列化和反序列化


image.png
public void test(){
        User user = new User("hx",22,true);
        Gson gson = new Gson();

        String json = gson.toJson(user);
        System.out.println(json);
    }
image.png

.将json字符串转换为java对象

User u2 = gson.fromJson(json,User.class);

Array数组的序列化和反序列化

也是使用toJson 和 fromJson来进行

image.png

Map和Set 的序列化和反序列化

需要使用TypeToken完成反序列化

image.png

六,RX思维(reactivex)

响应式思维
根据上一层的响应,影响下一层的变化

6.1 使用Rxjava进行下载图片

package com.lifang.rxjava;

import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import io.reactivex.Observable;
import io.reactivex.Observer;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;

public class MainActivity extends AppCompatActivity {
    private static final String PATH = "https://img1.baidu.com/it/u=604096226,2356671358&fm=253&fmt=auto&app=138&f=JPEG?w=750&h=500";
    //加载框
    private ProgressBar progressBar;
    private ImageView img1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //获取进度条
        progressBar = findViewById(R.id.progressBar);
        //获取图片
        img1 = findViewById(R.id.img1);
    }

    public void onLoadImg(View view) {

        /**
         * RX 思维
         * 只有起点->终点    被观察者  观察者
         */
        //起点
        Observable.just(PATH)
        //关联
                //需求 下载图片
                .map(new Function<String, Bitmap>() {
                    @Override
                    public Bitmap apply(String path) throws Exception {

                        try {
                            URL url = new URL(path);
                            HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
                            //设置请求时长 5秒不成功就是请求失败
                            httpURLConnection.setConnectTimeout(5000);
                            int responseCode = httpURLConnection.getResponseCode();//拿到服务器响应 200成功
                            if (responseCode == HttpURLConnection.HTTP_OK) {
                                //请求成功 服务器响应200
                                InputStream inputStream = httpURLConnection.getInputStream();//拿到这个输入流
                                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);//解流
//                                将bitmap向下一层流下去
                                return bitmap;
                            }

                        }catch (Exception e){
                            e.printStackTrace();
                        }
                        return null;
                    }
                })
                //给上层分配异步下载 图片下载操作
                .subscribeOn(Schedulers.io())
                //终点分配安卓主线程
                .observeOn(AndroidSchedulers.mainThread())
                //终点
                .subscribe(new Observer<Bitmap>() {// <String> 为什么是String ,上层响应影响下层变化
                    //订阅成功
                    @Override
                    public void onSubscribe(Disposable d) {
                        performTaskWithDelay();
                    }
                    // 拿到上层给的响应
                    @Override
                    public void onNext(Bitmap bitmap) {
                        img1.setImageBitmap(bitmap);//显示到控件上
                    }
                    // 链条思维发生异常
                    @Override
                    public void onError(Throwable e) {

                    }
                    //整个链条全部结束
                    @Override
                    public void onComplete() {
                        progressBar.setVisibility(View.INVISIBLE);
                    }
                });
    }

    private void performTaskWithDelay() {
        // 显示 ProgressBar
        progressBar.setVisibility(View.VISIBLE);

        // 模拟耗时操作
//        new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
//            @Override
//            public void run() {
//                // 完成任务后隐藏 ProgressBar
//                progressBar.setVisibility(View.INVISIBLE);
//            }
//        },3000); // 模拟3秒的耗时操作
    }
}

优点:可以在起点和终点之间增加需求,有需求添加一个.map()。
常用操作符,比如遍历数组
可以使用起点和终点的这种形式。

image.png

自定义解决Observer解决项目中服务器响应的问题

开发中,测试环境下登录功能没问题,但在正式环境下登录功能有问题

响应后服务端给我们响应的数据,然后我们从中只想拿到我们想要的数据

image.png
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容