运行有问题或需要源码请点赞关注收藏后评论区留言~~~
一、POST方式调用HTTP接口
POST方式把接口地址与请求报文分开,允许使用自定义的报文格式,由此扩大了该方式的应用场景。POST请求与GET请求主要有三处编码差异
1:在调用setRequestMethod方法时 请求方式填POST而非GET
2:POST方式务必调用setDoOutput方法并设置true,表示准备让连接执行输出操作
3:连接成功之后,要向连接对象的输出流写入请求报文的字节数据
接下来通过一个实例,演示如何在App开发中发送POST请求来更新应用版本。
此处要搭建HTTP服务器,过程省略不表,读者可自行上网查询
完成服务器搭建之后,通过电脑浏览器访问Web服务的默认首页,可以在命令行查找电脑的无线网址,如果能够正常打开网页,就表示在笔记本电脑上搭建好了HTTP服务器 效果如下
可自行在下拉框中选择要更新的应用
连接真机测试效果更好
代码如下
Java类
package com.example.chapter14; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; import com.example.chapter14.bean.PackageInfo; import com.example.chapter14.constant.ApkConstant; import com.example.chapter14.task.CheckUpdateTask; import com.example.chapter14.task.req.CheckUpdateReq; import com.example.chapter14.task.resp.CheckUpdateResp; import com.google.gson.Gson; public class HttpPostActivity extends AppCompatActivity implements CheckUpdateTask.OnCheckUpdateListener { private static final String TAG = "HttpPostActivity"; private Spinner sp_app_name; // 应用名称的下拉框 private ImageView iv_app; private TextView tv_app_result; private boolean isFirstSelect = true; // 是否首次选择 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_http_post); iv_app = findViewById(R.id.iv_app); tv_app_result = findViewById(R.id.tv_app_result); initAppSpinner(); // 初始化应用名称的下拉框 } // 初始化应用名称的下拉框 private void initAppSpinner() { ArrayAdapter<String> apkNameAdapter = new ArrayAdapter<String>(this, R.layout.item_select, ApkConstant.NAME_ARRAY); sp_app_name = findViewById(R.id.sp_app_name); sp_app_name.setPrompt("请选择要更新的应用"); sp_app_name.setAdapter(apkNameAdapter); sp_app_name.setOnItemSelectedListener(new AppNameSelectedListener()); sp_app_name.setSelection(0); } class AppNameSelectedListener implements AdapterView.OnItemSelectedListener { public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { if (isFirstSelect) { // 刚打开页面时不需要执行下载动作 isFirstSelect = false; return; } queryAppInfo(arg2); // 查询应用的详细信息 } public void onNothingSelected(AdapterView<?> arg0) {} } // 查询应用的详细信息 private void queryAppInfo(int pos) { iv_app.setImageResource(ApkConstant.ICON_ARRAY[pos]); // 设置图像视图的资源图片 CheckUpdateReq req = new CheckUpdateReq(); // 创建检查更新的请求对象 req.package_list.add(new PackageInfo(ApkConstant.PACKAGE_ARRAY[pos])); String content = new Gson().toJson(req); // 把检查更新的请求对象转换为json字符串 CheckUpdateTask task = new CheckUpdateTask(); // 创建一个检查应用更新的异步任务 task.setCheckUpdateListener(this); // 设置应用更新检查的监听器 task.execute(content); // 把应用更新检查任务加入到处理队列 } // 在结束应用更新检查时触发 @Override public void finishCheckUpdate(String resp) { if (TextUtils.isEmpty(resp)) { Toast.makeText(this, "应用检查更新失败", Toast.LENGTH_SHORT).show(); return; } // 把JSON串转换为对应结构的实体对象 CheckUpdateResp checkResp = new Gson().fromJson(resp, CheckUpdateResp.class); if (checkResp!=null && checkResp.package_list!=null && checkResp.package_list.size()>0) { PackageInfo info = checkResp.package_list.get(0); String desc = String.format("应用检查更新结果如下:\n应用名称:%s\n应用包名:%s\n最新版本:%s\n下载地址:%s", info.app_name, info.package_name, info.new_version, info.download_url); tv_app_result.setText(desc); // 显示当前选中应用的检查更新结果 } } }
APK类
package com.example.chapter14.constant; import com.example.chapter14.R; public class ApkConstant { public static String[] NAME_ARRAY = { "爱奇艺", "酷狗音乐", "美图秀秀", "微信", "淘宝", "QQ" }; public static String[] PACKAGE_ARRAY = { "com.qiyi.video", "com.kugou.android", "com.mt.mtxx.mtxx", "com.tencent.mm", "com.taobao.taobao", "com.tencent.mobileqq" }; public static int[] ICON_ARRAY = { R.drawable.icon_aiqiyi, R.drawable.icon_kugou, R.drawable.icon_meitu, R.drawable.icon_weixin, R.drawable.icon_taobao, R.drawable.icon_qq }; public static String[] URL_ARRAY = { "https://3g.lenovomm.com/w3g/yydownload/com.qiyi.video/60020", "https://3g.lenovomm.com/w3g/yydownload/com.kugou.android/60020", "https://3g.lenovomm.com/w3g/yydownload/com.mt.mtxx.mtxx/60020", "https://3g.lenovomm.com/w3g/yydownload/com.tencent.mm/60020", "https://3g.lenovomm.com/w3g/yydownload/com.taobao.taobao/60020", "https://3g.lenovomm.com/w3g/yydownload/com.tencent.mobileqq/60020" }; }
bean类
package com.example.chapter14.bean; public class PackageInfo { public String app_name; // 应用名称 public String package_name; // 应用包名 public String download_url; // 下载地址 public String new_version; // 新版本号 public PackageInfo() { app_name = ""; package_name = ""; download_url = ""; new_version = ""; } public PackageInfo(String package_name) { this.package_name = package_name; } }
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp" > <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" > <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:gravity="center" android:text="请选择要更新的应用:" android:textColor="@color/black" android:textSize="17sp" /> <Spinner android:id="@+id/sp_app_name" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:spinnerMode="dialog" /> </LinearLayout> <ImageView android:id="@+id/iv_app" android:layout_width="match_parent" android:layout_height="50dp" android:scaleType="fitCenter" /> <TextView android:id="@+id/tv_app_result" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout>
创作不易 觉得有帮助请点赞关注收藏~~~