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
關注下面二維碼,訂閱更多精彩内容。
關注公衆号(加好友):
作者:
王磊的部落格
出處:
http://vipstone.cnblogs.com/