Android 网络请求库Retrofit使用详解

简介: Android 网络请求库Retrofit使用详解

前言:

首先了解Retrofit注解,以下注解本人都会讲到.

1、首先在Android项目中引入需要的依赖

implementation 'com.github.bumptech.glide:glide:4.8.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

2、创建一个单例类,返回Retrofit对象

public class RetrofitManager {
    private RetrofitManager() {
    }
    /**
     * 1.首先使用Retrofit.Builder来构建一个Retrofit对象,
     * 2.baseUrl()方法用于指定所有Retrofit请求的根路径
     * 3.addConverterFactory()方法用于指定Retrofit在解析数据时所使用的转换库,这里指定成GsonConverterFactory
     * 用的是Gson库
     */
    public static Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://192.168.5.171:9102")
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    public static Retrofit getRetrofit() {
        return retrofit;
    }
}

3、创建对应的接口Api,写对应的请求方法和参数

public interface Api {
    @GET("/get/text")
    Call<JsonResult> getJson();
    @GET("/get/param")
    Call<ParamModel> getParam(@Query("keyword") String keyword,
                              @Query("page") int page,
                              @Query("order") int order);
    @GET("/get/param")
    Call<ParamModel> getParamQueryMap(@QueryMap Map<String, Object> queryMap);
    @POST("/post/string")
    Call<PostParamModel> getPostQuery(@Query("string") String string);
    @POST
    Call<PostParamModel> postParamUrl(@Url String url);
    @POST("/post/comment")
    Call<PostParamModel> postWithBody(@Body CommentBody body);
    /**
     * @Part 和 @Multipart结合使用 一般用于上传文件
     */
    @Multipart
    @POST("/file/upload")
    Call<PostParamModel> postUploadFile(@Part MultipartBody.Part part, @Header("token") String token);
    /**
     * @Part 和 @Multipart结合使用 一般用于上传文件
     */
    @Headers({"token:398429865hdsfhaj", "client:Android", "version:1.1.0"})
    @Multipart
    @POST("/files/upload")
    Call<PostParamModel> postUploadFiles(@Part ArrayList<MultipartBody.Part> parts);
    /**
     * @PartMap 一般用于上传文件和参数时使用。
     */
    @Multipart
    @POST("/file/params/upload")
    Call<PostParamModel> postUploadFileWithParams(@Part MultipartBody.Part part,
                                                  @PartMap Map<String, Object> map,
                                                  @HeaderMap Map<String, String> headerMap);
    @FormUrlEncoded
    @POST("/login")
    Call<PostParamModel> postLogin(@Field("userName") String userName,
                                   @Field("password") String password);
    @FormUrlEncoded
    @POST("/login")
    Call<PostParamModel> postLoginFileMap(@FieldMap Map<String, String> fieldMap);
    @Streaming
    @GET
    Call<ResponseBody> downloadFile(@Url String url);
}

4、创建对应的activity_request.xml

<?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">
    <data>
        <variable
            name="presenter"
            type="com.example.customview.retrofit.RequestActivity.Presenter" />
    </data>
    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/btn_request"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->presenter.getWithParams()}"
            android:text="getWithParams-@Query"
            android:textAllCaps="false"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
        <Button
            android:id="@+id/btn_request_query_map"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->presenter.getWithParamsQueryMap()}"
            android:text="getWithParams-@QueryMap"
            android:textAllCaps="false"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btn_request" />
        <Button
            android:id="@+id/btn_post_query"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->presenter.postParamQuery()}"
            android:text="postWithParam-@Query"
            android:textAllCaps="false"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btn_request_query_map" />
        <Button
            android:id="@+id/btn_post_url"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->presenter.postParamUrl()}"
            android:text="postWithParam-@Url"
            android:textAllCaps="false"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btn_post_query" />
        <Button
            android:id="@+id/btn_post_body"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->presenter.postWithBody()}"
            android:text="postWithBody-@Body"
            android:textAllCaps="false"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btn_post_url" />
        <Button
            android:id="@+id/btn_post_file"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->presenter.postUploadFile()}"
            android:text="postUploadFile"
            android:textAllCaps="false"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btn_post_body" />
        <Button
            android:id="@+id/btn_post_files"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->presenter.postUploadFiles()}"
            android:text="postUploadFiles"
            android:textAllCaps="false"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btn_post_file" />
        <Button
            android:id="@+id/btn_post_file_param"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->presenter.postUploadFileParams()}"
            android:text="postUploadFileParams"
            android:textAllCaps="false"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btn_post_files" />
        <Button
            android:id="@+id/btn_post_login"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->presenter.postLogin()}"
            android:text="postLogin-@Field"
            android:textAllCaps="false"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btn_post_file_param" />
        <Button
            android:id="@+id/btn_post_login_filed_map"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->presenter.postLoginFiledMap()}"
            android:text="postUploadFileParams-@FieldMap"
            android:textAllCaps="false"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btn_post_login" />
        <Button
            android:id="@+id/btn_post_down_load"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{()->presenter.downFile()}"
            android:text="downFile"
            android:textAllCaps="false"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/btn_post_login_filed_map" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

5、在对应的Activity进行编码,注释已经给出

/**
 * @Author: ly
 * @Date: 2023/2/24
 * @Description: Retrofit的使用
 */
public class RequestActivity extends AppCompatActivity {
    private static final String TAG = "RequestActivity";
    private ActivityRequestBinding binding;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_request);
        binding.setPresenter(new Presenter());
    }
    private Api getApi() {
        Retrofit retrofit = RetrofitManager.getRetrofit();
        return retrofit.create(Api.class);
    }
    public class Presenter {
        /**
         * get请求,请求参数为@Query
         */
        public void getWithParams() {
            //1.创建retrofit对象
            Api api = getApi();
            //3.当调用了Api.getParam()方法,就回返回Call<ParamModel>对象
            Call<ParamModel> call = api.getParam("测试", 10, 1);
            /**
             * 之后们再调用一下它的enqueue()方法Retrofit就会根据注解
             * 中配置的服务器接口地址去进行网络请求了,服务器响应的数据会回调到enqueue()方法中传
             * 入的Callback实现里面。需要注意的是,当发起请求的时候,Retrofit会自动在内部开启子线
             * 程,当数据回调到Callback中之后,Retrofit又会自动切换回主线程,整个操作过程中我们都
             * 不用考虑线程切换问题。在Callback的onResponse()方法中,调用response.body()方
             * 法将会得到Retrofit解析后的对象,也就是ParamModel类型的数据。
             */
            call.enqueue(new Callback<ParamModel>() {
                @Override
                public void onResponse(Call<ParamModel> call, Response<ParamModel> response) {
                    if (response.code() == HttpURLConnection.HTTP_OK) {
                        Log.i(TAG, "getWithParams: " + response.body());
                    }
                }
                @Override
                public void onFailure(Call<ParamModel> call, Throwable t) {
                }
            });
        }
        /**
         * get请求,请求参数为@QueryMap
         */
        public void getWithParamsQueryMap() {
            Api api = getApi();
            Map<String, Object> map = new HashMap<>();
            map.put("keyword", "关键字");
            map.put("page", 10);
            map.put("order", 0);
            Call<ParamModel> call = api.getParamQueryMap(map);
            call.enqueue(new Callback<ParamModel>() {
                @Override
                public void onResponse(Call<ParamModel> call, Response<ParamModel> response) {
                    Log.i(TAG, "getWithParamsQueryMap: " + response.body());
                }
                @Override
                public void onFailure(Call<ParamModel> call, Throwable t) {
                }
            });
        }
        /**
         * post请求,请求参数为@Query
         */
        public void postParamQuery() {
            Api api = getApi();
            Call<PostParamModel> call = api.getPostQuery("测试的新数据");
            call.enqueue(new Callback<PostParamModel>() {
                @Override
                public void onResponse(Call<PostParamModel> call, Response<PostParamModel> response) {
                    if (response.code() == HttpsURLConnection.HTTP_OK) {
                        Log.i(TAG, "postParamQuery: " + response.body());
                    }
                }
                @Override
                public void onFailure(Call<PostParamModel> call, Throwable t) {
                }
            });
        }
        /**
         * post请求,请求参数为@Url
         */
        public void postParamUrl() {
            String url = "post/string?string=Android开发";
            Api api = getApi();
            Call<PostParamModel> call = api.postParamUrl(url);
            call.enqueue(new Callback<PostParamModel>() {
                @Override
                public void onResponse(Call<PostParamModel> call, Response<PostParamModel> response) {
                    if (response.code() == HttpsURLConnection.HTTP_OK) {
                        Log.i(TAG, "postParamUrl: " + response.body());
                    }
                }
                @Override
                public void onFailure(Call<PostParamModel> call, Throwable t) {
                    Log.i(TAG, "postParamUrl: " + t.toString());
                }
            });
        }
        /**
         * post请求,请求参数注解@Body
         */
        public void postWithBody() {
            Api api = getApi();
            CommentBody body = new CommentBody("45651", "这条评论非常不错!");
            Call<PostParamModel> call = api.postWithBody(body);
            call.enqueue(new Callback<PostParamModel>() {
                @Override
                public void onResponse(Call<PostParamModel> call, Response<PostParamModel> response) {
                    if (response.code() == HttpURLConnection.HTTP_OK) {
                        Log.i(TAG, "postWithBody: " + response.body());
                    }
                }
                @Override
                public void onFailure(Call<PostParamModel> call, Throwable t) {
                }
            });
        }
        /**
         * post请求,进行单文件上传
         */
        public void postUploadFile() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                if (ContextCompat.checkSelfPermission(RequestActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageInfo.REQUESTED_PERMISSION_GRANTED
                        || ContextCompat.checkSelfPermission(RequestActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageInfo.REQUESTED_PERMISSION_GRANTED
                ) {
                    requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 200);
                } else {
                    InputPicture();
                }
            } else {
                InputPicture();
            }
        }
        /**
         * post请求,进行多文件上传
         */
        public void postUploadFiles() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                if (ContextCompat.checkSelfPermission(RequestActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageInfo.REQUESTED_PERMISSION_GRANTED
                        || ContextCompat.checkSelfPermission(RequestActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageInfo.REQUESTED_PERMISSION_GRANTED
                ) {
                    requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 300);
                } else {
                    postUploadImages();
                }
            } else {
                postUploadImages();
            }
        }
        /**
         * 文件上传并携带参数
         */
        public void postUploadFileParams() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                if (ContextCompat.checkSelfPermission(RequestActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageInfo.REQUESTED_PERMISSION_GRANTED
                        || ContextCompat.checkSelfPermission(RequestActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageInfo.REQUESTED_PERMISSION_GRANTED
                ) {
                    requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 400);
                } else {
                    postUploadImageParams();
                }
            } else {
                postUploadImageParams();
            }
        }
        /**
         * 登录
         */
        public void postLogin() {
            Call<PostParamModel> call = getApi().postLogin("Android开发", "a123456");
            call.enqueue(new Callback<PostParamModel>() {
                @Override
                public void onResponse(Call<PostParamModel> call, Response<PostParamModel> response) {
                    if (HttpURLConnection.HTTP_OK == response.code()) {
                        Log.i(TAG, "postLogin: " + response.body());
                    }
                }
                @Override
                public void onFailure(Call<PostParamModel> call, Throwable t) {
                    Log.i(TAG, "onFailure: " + t.toString());
                }
            });
        }
        /**
         * post请求进行登录,请求参数注解为@FieldMap
         */
        public void postLoginFiledMap() {
            Map<String, String> map = new HashMap<>();
            map.put("userName", "Android开发者");
            map.put("password", "a123456789");
            Call<PostParamModel> call = getApi().postLoginFileMap(map);
            call.enqueue(new Callback<PostParamModel>() {
                @Override
                public void onResponse(Call<PostParamModel> call, Response<PostParamModel> response) {
                    if (HttpURLConnection.HTTP_OK == response.code()) {
                        Log.i(TAG, "onResponse: " + response.body());
                    }
                }
                @Override
                public void onFailure(Call<PostParamModel> call, Throwable t) {
                    Log.i(TAG, "onResponse: " + t.toString());
                }
            });
        }
        /**
         * 文件下载
         */
        public void downFile() {
            Call<ResponseBody> call = getApi().downloadFile("/download/11");
            call.enqueue(new Callback<ResponseBody>() {
                @Override
                public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                    if (HttpURLConnection.HTTP_OK == response.code()) {
                        ResponseBody body = response.body();
                        //要知道文件名称
                        Headers headers = response.headers();
                        String fileNameHeader = headers.get("Content-disposition");
                        String fileName = "未命名.png";
                        if (fileName != null) {
                            fileName = fileNameHeader.replace("attachment; filename=", "");
                            Log.i(TAG, "fileName: " + fileName);
                        }
                        writeToDisk(response, fileName);
//                        for (int i = 0; i < headers.size(); i++) {
//                            String key = headers.name(i);
//                            String value = headers.value(i);
//                            Log.i(TAG, "key: " + key + " name:" + value);
//                            /**
//                             * 数据结果
//                             * key: Content-disposition name:attachment; filename=12.png
//                             * key: Content-Type name:application/x-msdownload
//                             * key: Content-Length name:66885
//                             * key: Date name:Sat, 25 Feb 2023 08:11:04 GMT
//                             */
//                        }
                    }
                }
                @Override
                public void onFailure(Call<ResponseBody> call, Throwable t) {
                    Log.i(TAG, "onFailure: " + t.toString());
                }
            });
        }
    }
    /**
     * 下载的文件写入到指定的文件中
     *
     * @param response
     * @param fileName
     */
    private void writeToDisk(Response<ResponseBody> response, String fileName) {
        String finalFileName = fileName;
        new Thread(() -> {
            InputStream inputStream = response.body().byteStream();
            File file = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
            File outFile = new File(file, finalFileName);
            Log.i(TAG, "file: " + file);
            FileOutputStream fileOutputStream = null;
            try {
                fileOutputStream = new FileOutputStream(outFile);
                byte[] bytes = new byte[1024];
                int len = 0;
                while ((len = inputStream.read(bytes)) != -1) {
                    fileOutputStream.write(bytes, 0, len);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    fileOutputStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
    /**
     * 文件上传携带参数
     */
    private void postUploadImageParams() {
        MultipartBody.Part part = createMultipartBodyPart("/sdcard/DCIM/Screenshots/Screenshot_2023-02-25-10-39-00-40_6ea35cac63846bc763be64f446db684d.jpg", "file");
        Map<String, Object> map = new HashMap<>();
        map.put("description", "这是筱路上传的图片");
        map.put("isFree", true);
        Map<String, String> headerMap = new HashMap<>();
        headerMap.put("token", "11111111111111111");
        headerMap.put("client", "iPhone20");
        headerMap.put("version", "1.0.2");
        Call<PostParamModel> call = getApi().postUploadFileWithParams(part, map, headerMap);
        call.enqueue(new Callback<PostParamModel>() {
            @Override
            public void onResponse(Call<PostParamModel> call, Response<PostParamModel> response) {
                if (HttpURLConnection.HTTP_OK == response.code()) {
                    Log.i(TAG, "postUploadImageParams: " + response.body());
                }
            }
            @Override
            public void onFailure(Call<PostParamModel> call, Throwable t) {
                Log.i(TAG, "onFailure: " + t.toString());
            }
        });
    }
    /**
     * 多文件上传
     */
    private void postUploadImages() {
        ArrayList<MultipartBody.Part> parts = new ArrayList<>();
        MultipartBody.Part partOne = createMultipartBodyPart("/sdcard/DCIM/Screenshots/Screenshot_2023-02-04-15-01-55-68_abc7e8e26578fbac9cdf97e1ea2cd1b5.jpg", "files");
        parts.add(partOne);
        MultipartBody.Part partTwo = createMultipartBodyPart("/sdcard/DCIM/Screenshots/Screenshot_2023-02-20-18-19-34-49.jpg", "files");
        parts.add(partTwo);
        MultipartBody.Part partThree = createMultipartBodyPart("/sdcard/DCIM/Screenshots/Screenshot_2023-02-25-10-39-00-40_6ea35cac63846bc763be64f446db684d.jpg", "files");
        parts.add(partThree);
        Api api = getApi();
        Call<PostParamModel> call = api.postUploadFiles(parts);
        call.enqueue(new Callback<PostParamModel>() {
            @Override
            public void onResponse(Call<PostParamModel> call, Response<PostParamModel> response) {
                Log.i(TAG, "code: " + response.code());
                if (HttpURLConnection.HTTP_OK == response.code()) {
                    Log.i(TAG, "postUploadImages: " + response.body());
                }
            }
            @Override
            public void onFailure(Call<PostParamModel> call, Throwable t) {
                Log.i(TAG, "onFailure: " + t.toString());
            }
        });
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 200) {
            InputPicture();
            Log.i(TAG, "onRequestPermissionsResult: ");
        } else if (requestCode == 300) {
            postUploadImages();
        } else if (requestCode == 400) {
            postUploadImageParams();
        }
    }
    /**
     * 单文件上传
     *
     * @param picturePath 图片路径
     */
    private void postUploadImage(String picturePath) {
        Api api = getApi();
        MultipartBody.Part part = createMultipartBodyPart(picturePath, "file");
        Call<PostParamModel> call = api.postUploadFile(part, "asfsafklio349823727859");
        call.enqueue(new Callback<PostParamModel>() {
            @Override
            public void onResponse(Call<PostParamModel> call, Response<PostParamModel> response) {
                if (response.code() == HttpURLConnection.HTTP_OK) {
                    Log.i(TAG, "postUploadFile: " + response.body());
                }
            }
            @Override
            public void onFailure(Call<PostParamModel> call, Throwable t) {
                Log.i(TAG, "onFailure: " + t.toString());
            }
        });
    }
    private MultipartBody.Part createMultipartBodyPart(String picturePath, String key) {
        File file = new File(picturePath);
        RequestBody body = RequestBody.create(MediaType.parse("image/jpg"), file);
        return MultipartBody.Part.createFormData(key, file.getName(), body);
    }
    private void InputPicture() {
        //Intent.ACTION_PICK 从数据中选择一个项目 (item),将被选中的项目返回。
        //MediaStore.Images.Media.EXTERNAL_CONTENT_URI 获取外部的URI
        Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        //参数一:对应的数据的URI 参数二:使用该函数表示要查找文件的MIME类型
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
        startActivityForResult(intent, 1);
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 1 && resultCode == RESULT_OK && null != data) {
            Uri selectedImage = data.getData();
            String[] filePathColumn = {MediaStore.Images.Media.DATA};
            Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            String picturePath = cursor.getString(columnIndex);
            Log.e("TAG", "onActivityResult: " + picturePath);
            postUploadImage(picturePath);
        }
    }
}

对应的Model就不给出了,需要的可以私信我要。


目录
相关文章
|
6天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
24 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
1月前
|
数据库 Android开发 开发者
构建高效Android应用:采用Kotlin协程优化网络请求处理
【2月更文挑战第30天】 在移动应用开发领域,网络请求的处理是影响用户体验的关键环节。针对Android平台,利用Kotlin协程能够极大提升异步任务处理的效率和简洁性。本文将探讨如何通过Kotlin协程优化Android应用中的网络请求处理流程,包括协程的基本概念、网络请求的异步执行以及错误处理等方面,旨在帮助开发者构建更加流畅和响应迅速的Android应用。
|
1月前
|
数据采集 JavaScript 前端开发
实用工具推荐:适用于 TypeScript 网络爬取的常用爬虫框架与库
实用工具推荐:适用于 TypeScript 网络爬取的常用爬虫框架与库
|
17天前
|
数据采集 大数据 数据安全/隐私保护
掌握网络抓取技术:利用RobotRules库的Perl下载器一览小红书的世界
本文探讨了使用Perl和RobotRules库在遵循robots.txt规则下抓取小红书数据的方法。通过分析小红书的robots.txt文件,配合亿牛云爬虫代理隐藏真实IP,以及实现多线程抓取,提高了数据采集效率。示例代码展示了如何创建一个尊重网站规则的数据下载器,并强调了代理IP稳定性和抓取频率控制的重要性。
掌握网络抓取技术:利用RobotRules库的Perl下载器一览小红书的世界
|
3天前
|
移动开发 Java Android开发
构建高效Android应用:采用Kotlin协程优化网络请求
【4月更文挑战第24天】 在移动开发领域,尤其是对于Android平台而言,网络请求是一个不可或缺的功能。然而,随着用户对应用响应速度和稳定性要求的不断提高,传统的异步处理方式如回调地狱和RxJava已逐渐显示出局限性。本文将探讨如何利用Kotlin协程来简化异步代码,提升网络请求的效率和可读性。我们将深入分析协程的原理,并通过一个实际案例展示如何在Android应用中集成和优化网络请求。
|
11天前
|
Android开发 开发者
Android网络和数据交互: 请解释Android中的AsyncTask的作用。
Android&#39;s AsyncTask simplifies asynchronous tasks for brief background work, bridging UI and worker threads. It involves execute() for starting tasks, doInBackground() for background execution, publishProgress() for progress updates, and onPostExecute() for returning results to the main thread.
10 0
|
11天前
|
网络协议 安全 API
Android网络和数据交互: 什么是HTTP和HTTPS?在Android中如何进行网络请求?
HTTP和HTTPS是网络数据传输协议,HTTP基于TCP/IP,简单快速,HTTPS则是加密的HTTP,确保数据安全。在Android中,过去常用HttpURLConnection和HttpClient,但HttpClient自Android 6.0起被移除。现在推荐使用支持TLS、流式上传下载、超时配置等特性的HttpsURLConnection进行网络请求。
10 0
|
23天前
|
数据采集 网络协议 API
python中其他网络相关的模块和库简介
【4月更文挑战第4天】Python网络编程有多个流行模块和库,如requests提供简洁的HTTP客户端API,支持多种HTTP方法和自动处理复杂功能;Scrapy是高效的网络爬虫框架,适用于数据挖掘和自动化测试;aiohttp基于asyncio的异步HTTP库,用于构建高性能Web应用;Twisted是事件驱动的网络引擎,支持多种协议和异步编程;Flask和Django分别是轻量级和全栈Web框架,方便构建不同规模的Web应用。这些工具使网络编程更简单和高效。
|
1月前
|
数据采集 存储 Scala
挖掘网络宝藏:利用Scala和Fetch库下载Facebook网页内容
本文介绍了如何使用Scala和Fetch库下载Facebook网页内容,同时通过爬虫代理服务(以亿牛云为例)绕过网络限制。代码示例展示了配置代理服务器、多线程爬取及内容存储的过程。注意实际应用时需替换代理服务器配置和目标URL,并考虑应对复杂的反爬虫机制。此方法兼顾匿名性和效率。
挖掘网络宝藏:利用Scala和Fetch库下载Facebook网页内容
|
1月前
|
机器学习/深度学习 算法框架/工具 Python
如何使用Python的Keras库构建神经网络模型?
如何使用Python的Keras库构建神经网络模型?
9 0