今天记录一下我的一个React Native Demo:

具体实现了对Android原生UI的封装和Android原生模块的封装,并且集成腾讯云点播的Android SDK。

功能:第一个页面显示腾讯云点播的视频播放控件,并播放一段视频。点击视频控件跳转到第二个页面。


步骤:

  一、创建React Native项目;

          react-native init TestDemo

  二、封装Android原生模块;

          在TestDemo/android下创建一个GoToActivity.java文件,此类继承ReactContextBaseJavaModule,实现其中的方法。

  三、封装Android原生UI;

          在TestDemo/android下创建一个自定义View,命名为CustomView;

          再创建一个ReactCustomViewManager.java文件,此类继承SimpleViewManager,泛型是我上面自定义的View,目的就是封装这个自定义View,给React Native使用。

  四、把写好的原生模块、原生UI进行注册;

         在TestDemo/android下创建一个MyReactPackage.java文件,此类继承ReactPackage,实现其中的方法,在createNativeModules方法中注册原生模块,在createViewManagers方法中注册原生UI。然后把MyReactPackage注册到MyApplication中getPackages方法中。

  五、下载腾讯云点播Android SDK(下载地址:http://download-1252463788.cossh.myqcloud.com/RTMPSDKAndroid2.0.2.2801.zip);

          将SDK的jniLibs文件夹拷贝到TestDemo/android/app/src/main/下;

       导入jar包,在Android Studio工程中找到刚才的jniLibs目录,展开目录,可以看到txrtmpsdk.jar,点击右键选择“Add As Library...”;

       在AndroidManifest.xml中配置APP的权限,音视频类APP一般需要以下权限:

       
       
       
       
       





  六、在自定义View--CustomView的布局中加入腾讯云点播的播放控件com.tencent.rtmp.ui.TXCloudVideoView;

  七、在JS端封装原生模块、原生UI,然后写一个页面进行测试。


源代码如下:

MainActivity.java

package com.yb;import android.content.Intent;import android.os.Bundle;import android.util.Log;import com.facebook.react.ReactActivity;import org.greenrobot.eventbus.EventBus;import org.greenrobot.eventbus.Subscribe;import org.greenrobot.eventbus.ThreadMode;public class MainActivity extends ReactActivity {    /**     * Returns the name of the main component registered from JavaScript.     * This is used to schedule rendering of the component.     */    @Override    protected String getMainComponentName() {        return "yb";    }    @Override    protected void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        EventBus.getDefault().register(this);    }    @Subscribe(threadMode = ThreadMode.MAIN)    public void getMqttMessage(String mqttMessage) {        Log.d("123pp", mqttMessage);        startActivity(new Intent(this, SecondActivity.class));    }    @Override    protected void onDestroy()    {        EventBus.getDefault().unregister(this);        super.onDestroy();    }}

MainApplication.java

package com.yb;import android.app.Application;import com.facebook.react.ReactApplication;import com.facebook.react.ReactNativeHost;import com.facebook.react.ReactPackage;import com.facebook.react.shell.MainReactPackage;import com.facebook.soloader.SoLoader;import java.util.Arrays;import java.util.List;public class MainApplication extends Application implements ReactApplication{    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this)    {        @Override        public boolean getUseDeveloperSupport()        {            return BuildConfig.DEBUG;        }        @Override        protected List getPackages()        {            return Arrays.asList(                    new MainReactPackage(),                    new MyReactPackage()            );        }    };    @Override    public ReactNativeHost getReactNativeHost()    {        return mReactNativeHost;    }    @Override    public void onCreate()    {        super.onCreate();        SoLoader.init(this, /* native exopackage */ false);    }}


GoToActivity.java

package com.yb;import com.facebook.react.ReactActivity;import android.widget.Toast;import com.facebook.react.bridge.NativeModule;import com.facebook.react.bridge.ReactApplicationContext;import com.facebook.react.bridge.ReactContext;import com.facebook.react.bridge.ReactContextBaseJavaModule;import com.facebook.react.bridge.ReactMethod;import org.greenrobot.eventbus.EventBus;import java.util.Map;import java.util.HashMap;public class GoToActivity extends ReactContextBaseJavaModule{    private static final String DURATION_SHORT_KEY = "SHORT";    private static final String DURATION_LONG_KEY = "LONG";    public GoToActivity(ReactApplicationContext reactContext)    {        super(reactContext);    }    /**     * getName方法。这个函数用于返回一个字符串名字,就是js中的模块名     */    @Override    public String getName()    {        return "GoToActivity";    }    /**     * 返回了需要导出给JavaScript使用的常量     */    @Override    public Map getConstants()    {        final Map constants = new HashMap<>();        constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);        constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);        return constants;    }    /**     * 导出给js使用的方法,需要使用注解@ReactMethod。方法的返回类型必须为void     */    @ReactMethod    public void show(String message, int duration)    {        Toast.makeText(getReactApplicationContext(), message, duration).show();        EventBus.getDefault().post(message);    }}


CustomView.java

package com.yb;import android.content.Context;import android.graphics.Color;import android.util.AttributeSet;import android.view.LayoutInflater;import android.widget.RelativeLayout;import android.widget.TextView;import com.tencent.rtmp.ui.TXCloudVideoView;/** * Created by Auser on 2017/5/2. */public class CustomView extends RelativeLayout{    private TextView textView;    private TXCloudVideoView txCloudVideoView;    public CustomView(Context context)    {        super(context);        init(context);    }    public CustomView(Context context, AttributeSet attrs)    {        super(context, attrs);        init(context);    }    public CustomView(Context context, AttributeSet attrs, int defStyleAttr)    {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        LayoutInflater.from(context).inflate(R.layout.customview_layout, this, true);        textView = (TextView) this.findViewById(R.id.tv01);        textView.setText("我是一个CustomView");        textView.setTextColor(Color.parseColor("#ff0000"));        txCloudVideoView = (TXCloudVideoView) this.findViewById(R.id.video_view);    }    public void setText(String txt) {        this.textView.setText(txt);    }    public String getText() {        return this.textView.getText().toString();    }    public TXCloudVideoView getTxCloudVideoView()    {        return txCloudVideoView;    }    public void setTxCloudVideoView(TXCloudVideoView txCloudVideoView)    {        this.txCloudVideoView = txCloudVideoView;    }}


MyReactPackage.java

package com.yb;import com.facebook.react.bridge.NativeModule;import com.facebook.react.bridge.ReactApplicationContext;import com.facebook.react.ReactPackage;import com.facebook.react.bridge.JavaScriptModule;import com.facebook.react.uimanager.ViewManager;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.Collections;public class MyReactPackage implements ReactPackage{    @Override    public List createNativeModules(            ReactApplicationContext reactContext)    {        List modules = new ArrayList<>();        modules.add(new GoToActivity(reactContext));        return modules;    }    @Override    public List> createJSModules()    {        // TODO Auto-generated method stub        return Collections.emptyList();    }    @Override    public List createViewManagers(            ReactApplicationContext reactContext)    {        return Arrays.asList(                new ReactCustomViewManager()        );    }}


ReactCustomViewManager.java

package com.yb;import android.support.annotation.Nullable;import android.util.Log;import android.webkit.WebView;import android.webkit.WebViewClient;import com.facebook.react.uimanager.SimpleViewManager;import com.facebook.react.uimanager.ThemedReactContext;import com.facebook.react.uimanager.annotations.ReactProp;import com.tencent.rtmp.TXLivePlayer;/** * Created by YiBing on 2017/4/28. */public class ReactCustomViewManager extends SimpleViewManager{    ThemedReactContext context;    public static final String REACT_CLASS = "RCTCustomView";    @Override    public String getName() {        return REACT_CLASS;    }    @Override    protected CustomView createViewInstance(ThemedReactContext reactContext) {        this.context = reactContext;        CustomView customView = new CustomView(reactContext);        return customView;    }    @ReactProp(name = "url")    public void setUrl(CustomView customView,@Nullable String url) {        Log.e("TAG", "setUrl");        customView.setText(url);        TXLivePlayer txLivePlayer = new TXLivePlayer(context);        txLivePlayer.setPlayerView(customView.getTxCloudVideoView());        txLivePlayer.startPlay(url, TXLivePlayer.PLAY_TYPE_VOD_MP4);    }}


SecondActivity.java

package com.yb;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import com.tencent.rtmp.ui.TXCloudVideoView;import com.tencent.rtmp.TXLivePlayer;public class SecondActivity extends AppCompatActivity{    @Override    protected void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_second);    }}


activity_second.xml

<?xml version="1.0" encoding="utf-8"?>    


customview_layout.xml

<?xml version="1.0" encoding="utf-8"?>    



CustomView.js

/** * Created by YiBing on 2017/4/28. * react-native: 0.43.3 * react-native-cli: 2.0.1 */import { PropTypes } from 'react';import { requireNativeComponent, View } from 'react-native';var iface = {    name: 'CustomView',    propTypes: {        url: PropTypes.string,        ...View.propTypes // include the default view properties    },};module.exports = requireNativeComponent('RCTCustomView', iface);


GoToActivity.js

/** * Created by YiBing on 2017/4/28. */'use strict';import {    NativeModules} from 'react-native';export default NativeModules.GoToActivity;// 以前的ES版本的写法。// var {NativeModules} = require('react-native');// module.exports = NativeModules.MyToast;


index.android.js

import React, { Component } from 'react';import {    AppRegistry,    StyleSheet,    Text,    View,    ListView,TouchableOpacity,Image,ToastAndroid,} from 'react-native';import GoToActivity from './GoToActivity';import CustomView from './CustomView';var video_url = "http://www.zxx.net.cn:8080//dmmm/vedio/201612270541078235250/201612270541078235250.mp4";export default class yb extends Component {  render() {    return (           腾讯云点播测试 GoToActivity.show("Go To SecondActivity", ToastAndroid.SHORT)}             style={{width:'100%', flex:1, justifyContent:'center', alignItems:'center',     borderWidth:10, borderColor:'#00f'}}>                                );  }}const styles = StyleSheet.create({  container: {    flex: 1,    justifyContent: 'center',    alignItems: 'center',    backgroundColor: '#F5FCFF',  },  welcome: {    fontSize: 20,    textAlign: 'center',    margin: 10,  },  instructions: {    textAlign: 'center',    color: '#333333',    marginBottom: 5,  },});AppRegistry.registerComponent('yb', () => yb);



程序显示效果图:





























更多相关文章

  1. IOS和Android(安卓)OpenGL游戏引擎的集成AdMob新版教程
  2. Android(安卓)面试题总结之Android(安卓)基础(一)
  3. 用fastboot大刷Android(安卓)~换个方法刷android手机
  4. android电子书App、自定义图表、仿腾讯漫画App、仿淘宝优惠券、3
  5. Android通过WebView与JS交互的全面方式
  6. Android中使用Handler机制更新UI的三种解决方案
  7. Android进程 Handler Message Looper
  8. 有关Android线程的学习
  9. Android开发艺术探索——第十章:Android的消息机制

随机推荐

  1. 【Mysql】实现中位数计算
  2. 约束数据库表,以便只有一行可以在列中具有
  3. sqlite developer过期解决办法
  4. python pandas库的应用(类比mysql语言)
  5. SQL Server 高可用性(一)AlwaysOn 技术
  6. 为什么我使用此Linq to Sql方法获得Inval
  7. PB中动态SQL处理BLOB的方式
  8. mysql-5.7.21-winx64.zip 下载安装(Win10)
  9. 网站速度慢及其解决方法
  10. 在Delete From语句中带有别名的表变量。