ReactNative绑定优酷SDK需要用到两部分知识:
优酷本身的sdk绑定;
RN与原生界面的交互;
效果:
RN版本:0.49.3
代码更新日期:2017.10.26
下文也根据绑定需要分为两部分:
一、优酷sdk绑定;
二、RN与原生页面的交互;
一、优酷SDK绑定
1.优酷云平台创建应用,获取到client_id和client_secret;
如图:
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和后置类;
页面代码:
android:id="@+id/baseview"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_alignParentTop="true" >
后置类代码:
packagecom.gangguwang.yewugo;importandroid.content.Intent;importandroid.support.v7.app.AppCompatActivity;importandroid.os.Bundle;importandroid.util.Log;importandroid.view.View;importandroid.widget.Button;importandroid.widget.Toast;importandroid.text.TextUtils;importcom.youku.cloud.player.YoukuPlayerConfig;importcom.youku.cloud.player.YoukuPlayerView;importcom.youku.cloud.utils.Logger;importcom.youku.cloud.module.PlayerErrorInfo;importcom.youku.cloud.player.PlayerListener;importcom.youku.cloud.player.VideoDefinition;importcom.youku.cloud.utils.ValidateUtil;importcom.youku.download.DownInfo;public class NativeActivity extendsAppCompatActivity {privateYoukuPlayerView youkuPlayerView;private String vid="XMzA1NzYwMTQxNg==";private String password="";private boolean local = false;
@Overrideprotected voidonCreate(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(newMyPlayerListener());
youkuPlayerView.setShowFullBtn(true);
autoplayvideo();
}private voidautoplayvideo() {if(local) {
youkuPlayerView.playLocalVideo(vid);
}else{if(TextUtils.isEmpty(password)) {
youkuPlayerView.playYoukuVideo(vid);
}else{
youkuPlayerView.playYoukuPrivateVideo(vid, password);
}
}
}
@Overrideprotected voidonPause() {super.onPause();//必须重写的onPause()
youkuPlayerView.onPause();
}
@Overrideprotected voidonResume() {super.onResume();//必须重写的onResume()
youkuPlayerView.onResume();
}
@Overrideprotected voidonDestroy() {super.onDestroy();//必须重写的onDestroy()
youkuPlayerView.onDestroy();
}//添加播放器的监听器
private class MyPlayerListener extendsPlayerListener {
@Overridepublic voidonComplete() {//TODO Auto-generated method stub
super.onComplete();
}
@Overridepublic void onError(intcode, PlayerErrorInfo info) {//TODO Auto-generated method stub//txt1.setText(info.getDesc());
}
@Overridepublic void OnCurrentPositionChanged(intmsec) {//TODO Auto-generated method stub
super.OnCurrentPositionChanged(msec);
}
@Overridepublic void onVideoNeedPassword(intcode) {//TODO Auto-generated method stub
super.onVideoNeedPassword(code);
}
@Overridepublic void onVideoSizeChanged(int width, intheight) {//TODO Auto-generated method stub
super.onVideoSizeChanged(width, height);
}
}
}
5.配置AndroidManifest.xml
5.1:给你的播放器Activity加上监听屏幕旋转的语句
5.2:添加权限
到此,优酷播放的sdk已经配置完毕。
二、RN与原生页面的互交
使用NativeModules模块互交,本章分为:
1.RN调用;
2.创建中间交互类IntentModule.java、IntentReactPackage.java;
3.使用反射和Intent进行通知原生界面;
1.RN调用代码:
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 ListcreateNativeModules(ReactApplicationContext reactContext) {return Arrays.asList(newIntentModule(reactContext)
);
}//@Override
//public List> createJSModules() {
//return Collections.emptyList();
//}
@Override
public ListcreateViewManagers(ReactApplicationContext reactContext) {returnCollections.emptyList();
}
}
代码解读:固定的api固定的方法必须重写createNativeModules和createViewManagers方法,只是把另一个交互类IntentModule注册到createNativeModules里面。
b).创建你的RN交互暴露方法类 IntentModule.java,代码如下:
packagecom.gangguwang.yewugo;importandroid.app.Activity;importandroid.content.Intent;importandroid.text.TextUtils;importcom.facebook.react.bridge.Callback;importcom.facebook.react.bridge.JSApplicationIllegalArgumentException;importcom.facebook.react.bridge.ReactApplicationContext;importcom.facebook.react.bridge.ReactContextBaseJavaModule;importcom.facebook.react.bridge.ReactMethod;public class IntentModule extendsReactContextBaseJavaModule {publicIntentModule(ReactApplicationContext reactContext) {super(reactContext);
}
@OverridepublicString getName() {return "IntentModule";
}/*** Activtiy跳转到JS页面,传输数据
*@paramsuccessBack
*@paramerrorBack*/@ReactMethodpublic voiddataToJS(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传递相关数据到原生
*@paramclassName
*@paramparams*/@ReactMethodpublic voidstartActivityFromJS(String className, String params){try{
Activity currentActivity=getCurrentActivity();if(null!=currentActivity){
Class toActivity=Class.forName(className);
Intent intent= newIntent(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
*@paramclassName
*@paramparams
*@paramrequestCode
*@paramsuccessBack
*@paramerrorBack*/@ReactMethodpublic void startActivityFromJSGetResult(String className, String params, intrequestCode, Callback successBack, Callback errorBack){try{
Activity currentActivity=getCurrentActivity();if(currentActivity != null) {
Class toActivity=Class.forName(className);
Intent intent= newIntent(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
@Overrideprotected ListgetPackages() {return Arrays.asList(newMainReactPackage(),newIntentReactPackage()
);
}
3.使用反射和Intent进行通知原生界面;
在IntentModule已经体现了,核心代码:
Activity currentActivity =getCurrentActivity();if(null!=currentActivity){
Class toActivity=Class.forName(className);
Intent intent= newIntent(currentActivity,toActivity);
intent.putExtra("params", params);
currentActivity.startActivity(intent);
}