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里面添加下面两段配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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初始化优酷播放代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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





本文转自王磊的博客博客园博客,原文链接:http://www.cnblogs.com/vipstone/p/7736577.html,如需转载请自行联系原作者

目录
相关文章
|
8月前
|
Java 开发工具 Android开发
逻辑清晰,详解社交源码Android开发SDK
前篇我们讲解了有关如何在IOS平台开发集成SDK,那么今天来给大家简单讲解下如何在社交源码Android客户端上开发集成 SDK。
逻辑清晰,详解社交源码Android开发SDK
|
8月前
|
API 开发工具 iOS开发
一点就通,社交源码IOS客户端开发集成SDK
所谓SDK,全称是SoftwaredevelopmentKit,翻译成软件开发工具包。SDK用助开发某种软件,今天给大家简单讲解下如何在社交源码IOS客户端上开发集成 SDK。
|
8月前
|
API 开发工具 iOS开发
一点就通,社交源码IOS客户端开发集成SDK
所谓SDK,全称是SoftwaredevelopmentKit,翻译成软件开发工具包。SDK用助开发某种软件,今天给大家简单讲解下如何在社交源码IOS客户端上开发集成 SDK。
|
开发工具
react-native run-android报错的原因,SDK位置未指定
react-native run-android报错的原因,SDK位置未指定
116 0
react-native run-android报错的原因,SDK位置未指定
|
开发工具 Android开发 容器
Android设计模式系列(1)--SDK源码之组合模式
原文链接:http://www.cnblogs.com/qianxudetianxia/archive/2011/07/29/2121488.html Android中对组合模式的应用,可谓是泛滥成粥,随处可见,那就是View和ViewGroup类的使用。
685 0
|
开发工具 Android开发
Android设计模式系列(2)--SDK源码之观察者模式
原文链接:http://www.cnblogs.com/qianxudetianxia/archive/2011/08/07/2129731.html 观察者模式,是一种非常常见的设计模式,在很多系统中随处可见,尤其是涉及到数据状态发生变化需要通知的情况下。
905 0
|
API 开发工具 Android开发
Android设计模式系列(3)--SDK源码之单例模式
原文链接:http://www.cnblogs.com/qianxudetianxia/archive/2011/08/07/2130306.html 单例模式,可以说是GOF的23种设计模式中最简单的一个。
971 0
|
Java 开发工具 Android开发
Android设计模式系列(7)--SDK源码之命令模式
原文链接:http://www.cnblogs.com/qianxudetianxia/archive/2011/08/13/2135478.html 命令模式,在.net,java平台的事件机制用的非常多,几乎每天都与之打交道。
973 0