自定義網(wǎng)絡(luò)請(qǐng)求工具(實(shí)現(xiàn)進(jìn)度條顯示(Android))

在ReactNative使用過程中,我們使用最多的是通過fetch的方法來訪問網(wǎng)絡(luò)。但是當(dāng)用于下載的時(shí)候,好像沒有什么好的辦法可以顯示進(jìn)度條。下面主要介紹的是在安卓原生中自定義網(wǎng)絡(luò)請(qǐng)求模塊來請(qǐng)求網(wǎng)絡(luò)并且顯示進(jìn)度。

首先用AndroidStudio打開RN項(xiàng)目下的android文件夾。我們可以看到一個(gè)很標(biāo)準(zhǔn)的安卓項(xiàng)目結(jié)構(gòu)。

Paste_Image.png

在項(xiàng)目中我們用已經(jīng)封裝好的OkHttp工具來實(shí)現(xiàn)在原生的網(wǎng)絡(luò)訪問。
在gradle下添加

compile 'com.zhy:okhttputils:2.6.2'

在Application對(duì)OkhttpUtils進(jìn)行初始化。

OkHttpClient okHttpClient = new OkHttpClient.Builder()
//                .addInterceptor(new LoggerInterceptor("TAG"))
            .connectTimeout(10000L, TimeUnit.MILLISECONDS)
            .readTimeout(10000L, TimeUnit.MILLISECONDS)
            //其他配置
            .build();
    OkHttpUtils.initClient(okHttpClient);

做好準(zhǔn)備工作,接下來就正式進(jìn)行自定義網(wǎng)絡(luò)模塊的封裝。

首先新建MyNetModule繼承ReactContextBaseJavaModule。直接放出代碼
public class MyNetModule  extends ReactContextBaseJavaModule{
    private static final String  REQUSETURL= "URL";
    private static final String  FILEPAHT = "PATH";
    public static  boolean myflag=false;
    public ProgressDialog mDialog,upDialog;




    public MyNetModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }
    @Override
    public String getName() {
        return "MyHttpRequest";
    }
    @ReactMethod
    public void download(final String url, final String filename) {
        mDialog=new ProgressDialog(getCurrentActivity());
        mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mDialog.setTitle("正在下載...");
        mDialog.setCancelable(true);
        mDialog.setCanceledOnTouchOutside(false);// 設(shè)置在點(diǎn)擊Dialog外是否取消Dialog進(jìn)度條
        mDialog.setMax(100);
        mDialog.setButton(DialogInterface.BUTTON_POSITIVE,"取消下載",new DialogInterface.OnClickListener(){
            @Override
            public void onClick(DialogInterface dialog, int which) {
                myflag=true;
                OkHttpUtils.getInstance().cancelTag(getCurrentActivity());
                File file=new File(Environment.getExternalStorageDirectory().getAbsolutePath(),filename);
                file.delete();
            }
        });
        mDialog.show();
        OkHttpUtils//
                .get()//
                .url(url)//
                .tag(getCurrentActivity())
                .build()//
                .execute(new FileCallBack(Environment.getExternalStorageDirectory().getAbsolutePath(), filename)//
                {
                    @Override
                    public void onError(Call call, Exception e, int id) {
                        mDialog.dismiss();
                        if (myflag) {
                            Toast.makeText(getCurrentActivity(), "下載失敗,用戶取消了下載", Toast.LENGTH_LONG).show();
                        } else {
                            Toast.makeText(getCurrentActivity(), "下載失敗", Toast.LENGTH_LONG).show();
                            Log.v("wt", e.getMessage());
                        }
                        myflag=false;
                    }
                    @Override
                    public void onResponse(File response, int id) {
                        mDialog.dismiss();
                        Toast.makeText(getCurrentActivity(),"下載成功",Toast.LENGTH_LONG).show();
                        Log.v("wt",response.getAbsolutePath());
                    }

                    @Override
                    public void inProgress(float progress, long total, int id) {

                        super.inProgress(progress, total, id);
                        mDialog.setProgress((int) (progress*100));
                        Log.v("wt", String.valueOf(progress));
                    }
                });
    }
    public class MyStringCallback extends StringCallback
    {
        @Override
        public void inProgress(float progress, long total, int id) {
            super.inProgress(progress, total, id);
            Log.v("up", String.valueOf(progress));
            upDialog.setProgress((int) (progress*100));
        }

        @Override
        public void onBefore(Request request, int id)
        {
        }

        @Override
        public void onAfter(int id)
        {
        }

        @Override
        public void onError(Call call, Exception e, int id)
        {
            upDialog.dismiss();
            Log.v("wt",e.getMessage());
        }

        @Override
        public void onResponse(String response, int id)
        {
            upDialog.dismiss();
            Log.e("wt", "onResponse:complete");
          Toast.makeText(getCurrentActivity(),"上傳成功",Toast.LENGTH_LONG).show();
        }

}
    @ReactMethod
    public void upload(String url, final String filename){
        upDialog=new ProgressDialog(getCurrentActivity());
        upDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        upDialog.setTitle("正在上傳...");
        upDialog.setCancelable(true);
        upDialog.setCanceledOnTouchOutside(false);// 設(shè)置在點(diǎn)擊Dialog外是否取消Dialog進(jìn)度條
        upDialog.setMax(100);
        upDialog.setButton(DialogInterface.BUTTON_POSITIVE,"取消上傳",new DialogInterface.OnClickListener(){
            @Override
            public void onClick(DialogInterface dialog, int which) {
                myflag=true;
                Toast.makeText(getCurrentActivity(),"用戶取消上傳",Toast.LENGTH_LONG).show();
                OkHttpUtils.getInstance().cancelTag(getCurrentActivity());

            }
        });
        upDialog.show();
        Map<String, String> headers = new HashMap<>();
        headers.put("application", "octet-stream");
        File file = new File(Environment.getExternalStorageDirectory(), filename);
        Log.v("wt", String.valueOf(file.exists()));
        OkHttpUtils
                .post().addFile("upload",filename,file)
                .url(url)
                .tag(getCurrentActivity())
                .build()
                .execute(new MyStringCallback());
          }
    }

在上面的代碼中。主要利用okhttpUtils實(shí)現(xiàn)了上傳和下載的功能以及用ProgressDialog顯示進(jìn)度。需要注意的是在getName()方法中返回的字符串,在js調(diào)用的時(shí)候會(huì)使用到。

封裝好了MyNetMoudule模塊。我們還需要在ReactPackage中對(duì)這個(gè)模塊進(jìn)行注冊(cè)。注冊(cè)的代碼如下。
public class RCTCommonToolsPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules=new ArrayList<>();
        modules.add( new RCTCommonTools(reactContext));
        modules.add(new MyNetModule(reactContext));
        return modules;
    }

    @Override
    public List<Class<? extends JavaScriptModule>> createJSModules() {
        return Collections.emptyList();
    }

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

上面的代碼主要是寫一個(gè)RCTCommonToolsPackage 類繼承于ReactPackage.并在里面實(shí)現(xiàn)其三個(gè)方法。在createNativeModules方法里面注冊(cè)我們自己定義的模塊

注冊(cè)完成后,我們還需要在MainApplication里面對(duì)我們自定義的package進(jìn)行注冊(cè)。主要代碼如下
 protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
              new RCTCommonToolsPackage(),
                new ReactImageZoom()
      );
    }
  };

到了這里,我們的自定義網(wǎng)絡(luò)模塊封裝完畢。
接下來是使用。

'use strict';
var { NativeModules } = require('react-native');
module.exports = NativeModules.MyHttpRequest;
'use strict';

import React, {Component} from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Image,
  TouchableOpacity,
  ToastAndroid,
  Alert,
  NativeModules

} from 'react-native';
var url="http://sw.bos.baidu.com/sw-search-sp/software/453ba7195c823/QQPhoneManager_5.6.1.5116.exe";
var fliename="my.apk";
var flie="my.apk";
var uploadurl='http://108.88.0.101:8080/uploadProgress/upload';
import MyHttpRequest from './DwithU.js'
export  default class AwesomeProject extends Component{

HttpDown(){
   MyHttpRequest.download(url,flie)
 }


HttpUp(){
 MyHttpRequest.upload(uploadurl,fliename)
}


  render() {
    return ( 
      <View style = { {flex: 1,justifyContent: 'center',alignItems: 'center' }}>
        <TouchableOpacity onPress = {this.HttpDown }style = {styles.button} >
          <Text > DOWN</Text>
        </TouchableOpacity>
        <TouchableOpacity onPress = {this.HttpUp} style = {styles.button } >
          <Text> UPLOAD </Text> 
        </TouchableOpacity> 
  
      </View>
    );
  }
}

var styles = StyleSheet.create({
  button: {
    width: 180,
    height: 50,
    justifyContent: 'center',
    backgroundColor: '#e2e2e2',
    alignItems: 'center',
    margin: 10,
  }
});

效果圖
Paste_Image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,881評(píng)論 25 709
  • 早早睡下,卻怎么也睡不著,索性起來寫寫現(xiàn)在的感受,就像村上春樹說的那樣好讓心靈有個(gè)心懷釋然的去處。 現(xiàn)在已經(jīng)過了冬...
    卿若安閱讀 193評(píng)論 0 0
  • 1.LIVE=EVIL,本是同根生。魔鬼屬靈,洞察譏諷詭辯誘惑,無(wú)一不通無(wú)一不對(duì)。愛與上帝爭(zhēng)奪人之靈,也就是搶奪生...
    道伊裘閱讀 624評(píng)論 0 2
  • 某型號(hào)路由器的緩沖區(qū)溢出就能危及成千上萬(wàn)的WiFi用戶 公共無(wú)線網(wǎng)絡(luò)的隱私和安全危害有了完美例證,一名以色列黑客展...
    實(shí)驗(yàn)吧閱讀 575評(píng)論 0 0
  • 今天,同事小可與米帥在茶水間吵起來了,據(jù)同事小八卦說,如果不是汪姐在中間橫著,兩人就動(dòng)上手了。還沒容我問原因,小八...
    寧青檸閱讀 3,641評(píng)論 0 0

友情鏈接更多精彩內(nèi)容