• react-native绑定优酷SDK-附效果图和源码


    ReactNative绑定优酷SDK需要用到两部分知识:

    • 优酷本身的sdk绑定;
    • RN与原生界面的交互;

    效果:

    RN版本:0.49.3

    代码更新日期:2017.10.26

    下文也根据绑定需要分为两部分:

      一、优酷sdk绑定; 

      二、RN与原生页面的交互;

    一、优酷SDK绑定

    1.优酷云平台创建应用,获取到client_id和client_secret;

      申请地址:http://cloud.youku.com/app

      如图:

    2.引入sdk:

    在目录app/libs加入优酷sdk:mma_sdk.jar、utdid4all-1.1.5.5.jar、YoukuPlayerOpenSDK-release.aar,sdk下载地址:http://cloud.youku.com/down/play

    在目录app/build.gradle里面添加下面两段配置:

    android {
        // ... 之前本身配置,下面为添加的配置
        //添加libs目录配置
        repositories {
            flatDir {
                dirs 'libs'
            }
        }
        sourceSets {
            main {
                jniLibs.srcDirs = ['libs'];
            }
        }
    
    }
    
    dependencies {
        // ... 之前本身配置,下面为添加的配置
        //公共库
        compile 'com.alibaba:fastjson:1.1.56.android'
        compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
        //sdk
        compile(name: 'YoukuPlayerOpenSDK-release', ext: 'aar')
    }
    

    3.在MainApplication.java初始化优酷播放代码:

    import com.youku.cloud.player.YoukuPlayerConfig;  
    
      //请在这里输入你的应用的clientId,clientSecret
      public static final String CLIENT_ID_WITH_AD = "e7e4d0ee1591b0bf";
      public static final String CLIENT_SECRET_WITH_AD = "1fbf633f8a55fa1bfabf95729d8e259a";
    
    @Override
      public void onCreate() {
        super.onCreate();
        SoLoader.init(this, /* native exopackage */ false);
    
        YoukuPlayerConfig.setClientIdAndSecret(CLIENT_ID_WITH_AD,CLIENT_SECRET_WITH_AD);
        YoukuPlayerConfig.onInitial(this);
        YoukuPlayerConfig.setLog(false);
      }
    

    4.新建Activity和后置类;

    页面代码:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.gangguwang.yewugo.YKPlayerActivity"
        android:orientation="vertical">
    
        <com.youku.cloud.player.YoukuPlayerView
            android:id="@+id/baseview"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true" >
        </com.youku.cloud.player.YoukuPlayerView>
        
    </LinearLayout>

    后置类代码:

    package com.gangguwang.yewugo;
    
    import android.content.Intent;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.Toast;
    import android.text.TextUtils;
    
    import com.youku.cloud.player.YoukuPlayerConfig;
    import com.youku.cloud.player.YoukuPlayerView;
    import com.youku.cloud.utils.Logger;
    import com.youku.cloud.module.PlayerErrorInfo;
    import com.youku.cloud.player.PlayerListener;
    import com.youku.cloud.player.VideoDefinition;
    import com.youku.cloud.utils.ValidateUtil;
    import com.youku.download.DownInfo;
    
    
    public class NativeActivity extends AppCompatActivity {
    
        private YoukuPlayerView youkuPlayerView;
        private String vid="XMzA1NzYwMTQxNg==";
        private String password="";
        private boolean local = false;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_native);
            // Intent mIntent=getIntent();
            // if(mIntent!=null) {
            //     Toast.makeText(this,"请求参数:"+mIntent.getStringExtra("params"),Toast.LENGTH_SHORT).show();;
            // }
            // Button btn_two=(Button)this.findViewById(R.id.btn_two);
            // //btn_two.setVisibility(View.GONE); //隐藏按钮
            // btn_two.setOnClickListener(new View.OnClickListener() {
            //     @Override
            //     public void onClick(View v) {
            //         Intent mIntent=new Intent(NativeActivity.this,MainActivity.class);
            //         mIntent.putExtra("data","你是123...");
            //         NativeActivity.this.startActivity(mIntent);
            //         NativeActivity.this.finish();
            //     }
            // });
            youkuPlayerView = (YoukuPlayerView)findViewById(R.id.baseview);
            // 初始化播放器
            youkuPlayerView.attachActivity(this);
            youkuPlayerView.setPreferVideoDefinition(VideoDefinition.VIDEO_HD);
            youkuPlayerView.setPlayerListener(new MyPlayerListener());
            youkuPlayerView.setShowFullBtn(true);
            autoplayvideo();
        }
    
        private void autoplayvideo() {
            if (local) {
                youkuPlayerView.playLocalVideo(vid);
            } else {
                if (TextUtils.isEmpty(password)) {
                    youkuPlayerView.playYoukuVideo(vid);
                } else {
                    youkuPlayerView.playYoukuPrivateVideo(vid, password);
                }
            }
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            // 必须重写的onPause()
            youkuPlayerView.onPause();
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            // 必须重写的onResume()
            youkuPlayerView.onResume();
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            // 必须重写的onDestroy()
            youkuPlayerView.onDestroy();
        }
    
        // 添加播放器的监听器
        private class MyPlayerListener extends PlayerListener {
            @Override
            public void onComplete() {
                // TODO Auto-generated method stub
                super.onComplete();
            }
    
            @Override
            public void onError(int code, PlayerErrorInfo info) {
                // TODO Auto-generated method stub
                //txt1.setText(info.getDesc());
            }
    
            @Override
            public void OnCurrentPositionChanged(int msec) {
                // TODO Auto-generated method stub
                super.OnCurrentPositionChanged(msec);
            }
    
            @Override
            public void onVideoNeedPassword(int code) {
                // TODO Auto-generated method stub
                super.onVideoNeedPassword(code);
            }
    
            @Override
            public void onVideoSizeChanged(int width, int height) {
                // TODO Auto-generated method stub
                super.onVideoSizeChanged(width, height);
            }
        }
    
    }

    5.配置AndroidManifest.xml

     5.1:给你的播放器Activity加上监听屏幕旋转的语句

    <activity android:name=".NativeActivity" 
        android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout|uiMode"
        android:exported="true"
        android:launchMode="singleTask" />

      5.2:添加权限

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />

    到此,优酷播放的sdk已经配置完毕。

    二、RN与原生页面的互交

    使用NativeModules模块互交,本章分为:

      1.RN调用;

      2.创建中间交互类IntentModule.java、IntentReactPackage.java;

      3.使用反射和Intent进行通知原生界面;

    1.RN调用代码:

    <Button
        onPress={() => {
            NativeModules.IntentModule.startActivityFromJS('你的包名.NativeActivity', '参数');
        }}
        title="  播 放  "
        color="#841584"
    />

    2.创建中间交互类

    a).注册原生模块类 IntentReactPackage.java 代码如下:

    package com.gangguwang.yewugo;
    
    import com.facebook.react.ReactPackage;
    import com.facebook.react.bridge.JavaScriptModule;
    import com.facebook.react.bridge.NativeModule;
    import com.facebook.react.bridge.ReactApplicationContext;
    import com.facebook.react.uimanager.ViewManager;
    
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;
    
    
    public class IntentReactPackage implements ReactPackage {
        @Override
        public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
            return Arrays.<NativeModule>asList(
                    new IntentModule(reactContext)
            );
        }
        // @Override
        // public List<Class<? extends JavaScriptModule>> createJSModules() {
        //     return Collections.emptyList();
        // }
    
        @Override
        public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
            return Collections.emptyList();
        }
    }

    代码解读:固定的api固定的方法必须重写createNativeModules和createViewManagers方法,只是把另一个交互类IntentModule注册到createNativeModules里面。

    b).创建你的RN交互暴露方法类 IntentModule.java,代码如下:

    package com.gangguwang.yewugo;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.text.TextUtils;
    
    import com.facebook.react.bridge.Callback;
    import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
    import com.facebook.react.bridge.ReactApplicationContext;
    import com.facebook.react.bridge.ReactContextBaseJavaModule;
    import com.facebook.react.bridge.ReactMethod;
    
    
    public class IntentModule  extends ReactContextBaseJavaModule {
    
        public IntentModule(ReactApplicationContext reactContext) {
            super(reactContext);
        }
    
        @Override
        public String getName() {
            return "IntentModule";
        }
    
        /**
         * Activtiy跳转到JS页面,传输数据
         * @param successBack
         * @param errorBack
         */
        @ReactMethod
        public void dataToJS(Callback successBack, Callback errorBack){
            try{
                Activity currentActivity = getCurrentActivity();
                String result = currentActivity.getIntent().getStringExtra("data");
                if (TextUtils.isEmpty(result)){
                    result = "没有数据";
                }
                successBack.invoke(result);
            }catch (Exception e){
                errorBack.invoke(e.getMessage());
            }
        }
        /**
         * 从JS页面跳转到原生activity   同时也可以从JS传递相关数据到原生
         * @param className
         * @param params
         */
        @ReactMethod
        public void startActivityFromJS(String className, String params){
            try{
                Activity currentActivity = getCurrentActivity();
                if(null!=currentActivity){
                    Class toActivity = Class.forName(className);
                    Intent intent = new Intent(currentActivity,toActivity);
                    //intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    intent.putExtra("params", params);
                    currentActivity.startActivity(intent);
                }
    
            }catch(Exception e){
                throw new JSApplicationIllegalArgumentException("不能打开Activity : "+e.getMessage());
            }
        }
    
        /**
         * 从JS页面跳转到Activity界面,并且等待从Activity返回的数据给JS
         * @param className
         * @param params
         * @param requestCode
         * @param successBack
         * @param errorBack
         */
        @ReactMethod
        public void startActivityFromJSGetResult(String className, String params, int requestCode, Callback successBack, Callback errorBack){
            try {
                Activity currentActivity = getCurrentActivity();
                if(currentActivity != null) {
                    Class toActivity = Class.forName(className);
                    Intent intent = new Intent(currentActivity,toActivity);
                    //intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    intent.putExtra("params", params);
                    currentActivity.startActivityForResult(intent,requestCode);
                    // //进行回调数据
                    // successBack.invoke(MainActivity.mQueue.take());
                }
            } catch (Exception e) {
                errorBack.invoke(e.getMessage());
                e.printStackTrace();
            }
        }
    
        // /**
        //  * 必须添加反射注解不然会报错
        //  * 这个方法就是ReactNative将要调用的方法,会通过此类名字调用
        //  * @param msg
        //  */
        // @ReactMethod
        // public void callNativeMethod(String msg) {
        //     Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
        //     //startActivityForResult(myIntent, 1);
        // }
    
    }

    c).在MainApplication.java里面设置交互类IntentReactPackage

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
          new IntentReactPackage()
      );
    }

    3.使用反射和Intent进行通知原生界面;

    在IntentModule已经体现了,核心代码:

    Activity currentActivity = getCurrentActivity();
    if(null!=currentActivity){
        Class toActivity = Class.forName(className);
        Intent intent = new Intent(currentActivity,toActivity);
        intent.putExtra("params", params);
        currentActivity.startActivity(intent);
    }

    到此为止已经全部大功告成!源码地址:https://github.com/vipstone/react-native-youku

  • 相关阅读:
    redis 之redis集群与集群配置
    redis 之redis-sentinel主从复制高可用
    Python 基础之函数的嵌套与nonlocal修改局部变量及闭包函数
    Rocket
    Rocket
    Rocket
    Rocket
    Rocket
    Rocket
    Rocket
  • 原文地址:https://www.cnblogs.com/vipstone/p/7736577.html
Copyright © 2020-2023  润新知