自定义网络请求工具(实现进度条显示(Android))

在ReactNative使用过程中,我们使用最多的是通过fetch的方法来访问网络。但是当用于下载的时候,好像没有什么好的办法可以显示进度条。下面主要介绍的是在安卓原生中自定义网络请求模块来请求网络并且显示进度。

首先用AndroidStudio打开RN项目下的android文件夹。我们可以看到一个很标准的安卓项目结构。

Paste_Image.png

在项目中我们用已经封装好的OkHttp工具来实现在原生的网络访问。
在gradle下添加

compile 'com.zhy:okhttputils:2.6.2'

在Application对OkhttpUtils进行初始化。

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

做好准备工作,接下来就正式进行自定义网络模块的封装。

首先新建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);// 设置在点击Dialog外是否取消Dialog进度条
        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);// 设置在点击Dialog外是否取消Dialog进度条
        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实现了上传和下载的功能以及用ProgressDialog显示进度。需要注意的是在getName()方法中返回的字符串,在js调用的时候会使用到。

封装好了MyNetMoudule模块。我们还需要在ReactPackage中对这个模块进行注册。注册的代码如下。
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();
    }
}

上面的代码主要是写一个RCTCommonToolsPackage 类继承于ReactPackage.并在里面实现其三个方法。在createNativeModules方法里面注册我们自己定义的模块

注册完成后,我们还需要在MainApplication里面对我们自定义的package进行注册。主要代码如下
 protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
              new RCTCommonToolsPackage(),
                new ReactImageZoom()
      );
    }
  };

到了这里,我们的自定义网络模块封装完毕。
接下来是使用。

'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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,413评论 25 707
  • 早早睡下,却怎么也睡不着,索性起来写写现在的感受,就像村上春树说的那样好让心灵有个心怀释然的去处。 现在已经过了冬...
    卿若安阅读 157评论 0 0
  • 1.LIVE=EVIL,本是同根生。魔鬼属灵,洞察讥讽诡辩诱惑,无一不通无一不对。爱与上帝争夺人之灵,也就是抢夺生...
    道伊裘阅读 565评论 0 2
  • 某型号路由器的缓冲区溢出就能危及成千上万的WiFi用户 公共无线网络的隐私和安全危害有了完美例证,一名以色列黑客展...
    实验吧阅读 519评论 0 0
  • 今天,同事小可与米帅在茶水间吵起来了,据同事小八卦说,如果不是汪姐在中间横着,两人就动上手了。还没容我问原因,小八...
    宁青柠阅读 3,305评论 0 0