腾讯 移动开发者接入指南

接入指南

加入 QQJSSDK.framework ,其中包含了 JS API 的插件管理器方法。下载所需 js 文件 包括:jsbridge.js。 cdn

备注

jsbridge.js : 白名单内的为可以走sdk.js中的mqq.invoke逻辑;

如果不在白名单,走老逻辑QZAppExternal;

[最终协议格式为](jsbridge://namespace/method?param=test¶m2=xxx¶m3=yyy#123)

android 开发指引

导入 SDK : 导入开发工具包 QQJsSdkQB.jar(若项目已经引入 TBS,请引入 TBSQQJsSDK.jar

备注

SDK中包含:

- 插件基类WebViewPlugin

- 插件引擎WebViewPluginEngine

- 引擎内的插件容器及插件配置WebViewPluginContainer与WebViewPluginConfig

自定义插件 : 继承类 WebViewPlugin

类 WebViewPlugin 说明:

public DefaultPluginRuntime mRuntime;//插件的运行时对象, 可以获取当前context、Activity、WebView等实例

protected void onCreate(){} // 插件创建时被调用, 可以重载做插件的初始化工作, 建议不要放太多的逻辑, 一些不常用的数据可以放到首次使用时初始化.

protected void onDestroy(){} //插件销毁时被调用, 可以重载做插件的回收工作.

/**

Webview里有JS调用会执行这个方法, 重载以实现自己的API

@param url 触发接口的jsbridge伪协议

@param pkgName 接口的包名

@param method 方法名

@param args[] 参数

@return 根据pkgName和method判断是否处理, true表示已处理, API调用结束, false表示未处理, API调用会继续传给下一个插件处理.

*/

protected boolean handleJsRequest(String url, String pkgName, String method, String... args) {..}

public void onActivityResult(Intent intent, byte requestCode, int resultCode){}//启动activity

public void startActivityForResult(Intent intent, byte requestCode){}//获取来自activity的result

public void callJs(String func, JSONObject data){}//用于回传数据给web端,参见getResult

Example:ShortcutPlugin

 @Override

protected boolean handleJsRequest(String url, String pkgName, String method, String... args) {

if ("addShortcut".equals(method)) {

try {

JSONObject json = new JSONObject(args[0]);

//成功、失败回调

callback = json.optString(KEY_CALLBACK);

Shortcut shortcut = new Shortcut();

shortcut.setScheme(json.optString("scheme"));

shortcut.setTitle(json.optString("title"));

shortcut.setIcon(json.optString("icon"));

doAddShortcut(shortcut);//内部逻辑

} catch (JSONException e) {

e.printStackTrace();

}

}

return super.handleJsRequest(url, pkgName, method, args);

}

调用插件引擎 :

  • 在 layout 和 ava 代码中使用 CustomWebView 代替系统的 WebView 类
  • 参考如下 onCreate 初始化,其中 AuthorizeConfig 用于权限控制,需要继承实现调用插件引擎的 insertPlugin 方法将所需插件 list 注册到插件引擎的插件容器中
  • 实现 WebViewPluginContainer 接口,在 pluginStartActivityForResult 和 onActivityResult 实现 result 的派发
  • 在 onResume/onPause/onDestory 中加入相应的解决内存泄漏的代码

Example :

import com.tencent.mobileqq.webviewplugin.*;// import webviewplugin 的所有类

public class MyActivity extends Activity implements WebViewPluginContainer{// 声明实现 WebViewPluginContainer

CustomWebView webview;

protected WebViewPluginEngine mPluginEngine;

private PluginInfo[] pluginInfos= {new PluginInfo(ShareApiPlugin.class,"share", "mqq.share.* API", "1.0")};

protected void onCreate(Bundle savedInstanceState) {

webview=(CustomWebView) this.findViewById(R.id.webview);

mPluginEngine = new WebViewPluginEngine(WebViewPluginConfig.list,new DefaultPluginRuntime(webview,this));// 设置 common API

mPluginEngine.insertPlugin(pluginInfos);// 将插件添加入引擎中,pluginInfos为插件list

webview.setWebViewClient(new CustomWebViewClient(mPluginEngine));// 监听WebView

webview.setWebChromeClient(new CustomWebChromeClient(mPluginEngine));

webview.getSettings().setJavaScriptEnabled(true);

webview.getSettings().setUserAgentString("QQJSSDK/1.0.0 Android");

AuthorizeConfig.setClass(com.example.demo.QQAuthorizeConfig.class);// 设置 API 的权限配置

}

@Override

protected void onResume() {

super.onResume();

if (Build.VERSION.SDK_INT >= 11) {

webview.onResume();

} else {

}

}

@Override

protected void onPause() {

super.onPause();

if (Build.VERSION.SDK_INT >= 11) {

webview.onPause();

} else {

}

}

@Override

protected void onDestroy() {

super.onDestroy();

mPluginEngine.onDestroy(); //重要, 一定要加, 防止内存泄露

webview.destroy();

}

@Override

public int pluginStartActivityForResult(WebViewPlugin plugin, Intent intent, byte requestCode) {

return WebViewPlugin.defaultPluginStartActivityForResult(this, plugin, intent, requestCode);

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

if (WebViewPlugin.defaultPluginOnActivityResult(mPluginEngine, requestCode, resultCode, data)) {

return;

}

}

}

分发请求 : 调用插件引擎的 handleJsRequest 将请求分发给对应的插件。

iOS 开发指引

引入自定义 UI 控制类 :引入自己的 UIViewController 类,在该类类别中遵循 AppWebViewProtocol 协议,并实现协议方法

@interface AppWebViewController : UIViewController

@end

@interface AppWebViewController(JSAPI) <AppWebViewProtocol>

-(NSURL*)getPageURL;

-(NSString *)executeJsScript:(NSString*)script;

@end

嵌入 Webview :在自己的 UIViewController 中嵌入 UIWebview,并按照正常的 UIWebview 加载方法进行加载,并且必须实现 UIWebViewDelegate 中的如下方法

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType

{

//把请求交给webview插件管理器处理,以后所有schema请求都放这里面注册成插件来处理

if ([[QQJSWebViewPluginEngine getInstance] handleSchemaRequest:request.URL fromWebview:self]) {

return NO;

}

return YES;

}

- (void)webViewDidStartLoad:(UIWebView *)webView

{

//TO DO ....

[[QQWebViewPluginEngine getInstance] handleEvent:QQWebViewEventLoadStart userInfo:nil fromWebview:self];

//TO DO ....

}

- (void)webViewDidFinishLoad:(UIWebView *)webView

{

//TO DO ....

[[QQWebViewPluginEngine getInstance] handleEvent:QQWebViewEventLoadFinish userInfo:nil fromWebview:self];

//TO DO ....

}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error

{

//TO DO ....

[[QQWebViewPluginEngine getInstance] handleEvent:QQWebViewEventLoadFail userInfo:@{@"error":error} fromWebview:self];

//TO DO ....

}

插件进行事件处理 : 在 UIViewController 的生命周期方法中让插件进行事件处理

-(void)viewWillAppear:(BOOL)animated {

//TO DO ....

[[QQWebViewPluginEngine getInstance] handleEvent:QQWebViewEventWillAppear userInfo:nil fromWebview:self];

//TO DO ....

}

- (void)viewDidAppear:(BOOL)animated{

//TO DO ....

[[QQWebViewPluginEngine getInstance] handleEvent:QQWebViewEventDidAppear userInfo:nil fromWebview:self];

//TO DO ....

}

- (void)viewWillDisappear:(BOOL)animated{

//TO DO ....

[[QQWebViewPluginEngine getInstance] handleEvent:QQWebViewEventWillDisappear userInfo:nil fromWebview:self];

//TO DO ....

}

- (void)viewDidDisappear:(BOOL)animated{

//TO DO ....

[[QQWebViewPluginEngine getInstance] handleEvent:QQWEbViewEventDidDisappear userInfo:nil fromWebview:self];

//页面被销毁时插件也要销毁

if([self isOrphan:self])

{

[[QQWebViewPluginEngine getInstance] handleWebviewDestory:self];

}

//TO DO ....

}

- (BOOL)isOrphan:(UIViewController *)viewController{

if (viewController) {

if (viewController.parentViewController && [viewController.parentViewController isKindOfClass:[UINavigationController class]]) {

//如果viewController是放在navigationController里的,我们应该判断该navigationController

return [self isOrphan:viewController.navigationController];

}

else {

//否则直接判断,如果viewController又没parent又没被present,则返回YES

return !viewController.parentViewController && !viewController.presentingViewController;

}

}

return YES;

}

view 的生命周期方法需按照上面的实现方法进行,绿色 TODO 部分可用来写入其他处理,完成上面步骤即可开始调用 JS API

建立自己的插件类 : 建立自己的插件类,并继承 QQJSBridgePluginHelper

#import <Foundation/Foundation.h>

#import "QQJSBridgePluginHelper.h"

@interface QQJSBridgeDemoPlugin : QQJSBridgePluginHelper

@end

注册插件 : 在 QQWebViewPluginConfigs.h 中注册该插件,其中 func 字段的值是插件的模块名

@"com.tencent.sng.app.jsbridge.device": @{

@"cls": [QQJSBridgeDemoPlugin class],

@"desc": @"JSBridge Demo Module Plugin",

@"ver": @"1.0.0",

@"func": @[@"device"]

},

实现自定义插件方法并命名 : 在该类中实现自己的插件方法按照 handleJsBridgeRequest 模块名方法名的格式来命名插件方法

#import "QQJSBridgeDemoPlugin.h"

@implementation QQJSBridgeDemoPlugin

#pragma mark - mqq.offline

#define kJsCallback @"callback"

#define kJS_NULL_STR @"null"

#define kSyncCallTimeout dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC)

#define kAsyncCallTimeout DISPATCH_TIME_FOREVER

-(id)init

{

self = [super init];

if (self) {

}

return self;

}

- (id)handleJsBridgeRequest_device_isMobileQQ:(NSDictionary*)params

{

NSLog(@"handleJsBridgeRequest_device_isMobileQQ");

return nil;

}

//旧接口:执行更新并返回更新结果

- (id)handleJsBridgeRequest_offline_update:(NSDictionary*)params

{

//业务BID

NSString *bid = [NSString stringWithFormat:@"%@", [params objectForKey:@"bid"]];

NSString *updateJsCallback = [params objectForKey:kJsCallback];

//防止参数为空

if (!updateJsCallback || !bid)

{

[self evaluateOfflineJavascript:updateJsCallback event:0 ret:0 response:nil];

return nil;

}

//通知JS:event为0,代表本地是否缓存

[self evaluateOfflineJavascript:updateJsCallback event:0 ret:0 response:nil];

return nil;

}

- (void)evaluateOfflineJavascript:(NSString*)callback event:(int)event ret:(int)ret response:(NSString*)response

{

//需要执行的JS脚本

NSString *script = [NSString stringWithFormat:@"%@(%d, %d, %@)", callback, event, ret, response ? response : kJS_NULL_STR];

[self evaluateOfflineJavascript:script];

}

- (void)evaluateOfflineJavascript:(NSString*)script

{

if ([NSThread isMainThread])

{

[self.webViewController executeJsScript:script];

}

else

{

dispatch_async(dispatch_get_main_queue(), ^{

[self.webViewController executeJsScript:script];

});

}

}

@end

开发者规范

综述 : 开发者开发时,除了需要满足每个接口的规范限制、调用频率限制外,还需特别注意模版消息、用户数据等敏感信息的使用规范。

涉及用户数据时

您的服务需要收集用户任何数据的,必须事先获得用户的明确同意,且仅应当收集为运营及功能实现目的而必要的用户数据, 同时应当告知用户相关数据收集的目的、范围及使用方式等,保障用户知情权。 您收集用户的数据后,必须采取必要的保护措施,防止用户数据被盗、泄漏等。 如果腾讯认为您收集、使用用户数据的方式,可能损害用户体验,腾讯有权要求您删除相关数据并不得再以该方式收集、使用用户数据。 一旦您停止使用本服务,或腾讯基于任何原因终止您使用本服务,您必须立即删除全部因使用本服务而获得的数据(包括各种备份), 且不得再以任何方式进行使用。

其他规范

请勿设置或发布任何违反相关法规、公序良俗、社会公德等的玩法、内容等。 请勿公开表达或暗示,您与腾讯之间存在合作关系,包括但不限于相互持股、商业往来或合作关系等,或声称腾讯对您的认可。 完整的开发者规范和接口限制,请详见开发者接口文档

以上是 腾讯 移动开发者接入指南 的全部内容, 来源链接: utcz.com/z/264299.html

回到顶部