背景:离线webapp模式打包,利用插件可以实现h5与原生之间双向调用,但是仅仅是基于启动sdk的那个Activity或者是Controller,有时候需要在任何一个原生的界面都能够调用h5的指定的页面,经过反复研究、多次请教官方的技术人员,终于得以实现,数据共享、插件调用都没有问题。
[有不清楚的地方联系qq:852085282,不喜勿喷!]
实现思路:
-
安卓: 新启动一个Activity,获取EntryProxy单例,动态修改为webview模式,根据指定的html页面路径,创建一个webview,添加到新的Activity上面。【注意在h5页面点击返回的时候,需要定制mui.back事件,调用plus.runtime.quit();来关闭这个Activity】
-
苹果: 新启动一个UIViewController,根据指定的html页面路径,创建一个PDRCoreAppFrame视图,作为新UIViewController的subview.【注意:在h5页面返回的时候,需要通过插件的方式通知原生app去获取当前显示在最上层的UIViewController做出关闭动作】
具体代码:
- 安卓:在需要的地方调用:
Intent intent = new Intent( this, WebviewActivity.class); String _url = "h5page.html";// 此处还可以在url里传递数据 intent.putExtra("url", _url); this.startActivity(intent);
关键的部分就是那个WebviewActivity.java, 具体见下方代码。
- 苹果:在需要的地方调用:
H5WebviewController *vc = [[H5WebviewController alloc] init]; vc.page = @"userpage.html?userid=1000011"; [self presentViewController:vc animated: YES completion:nil];// 此处也可以push的方式
关键的部分就是那个H5WebviewController类, 具体见下方代码。
封装的2个原生界面代码:
WebviewActivity.java 如下:
public class WebviewActivity extends Activity {
IWebview webview = null;
EntryProxy mEntryProxy = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
mEntryProxy = EntryProxy.getInstnace();
mEntryProxy.onCreate(this, savedInstanceState, SDK.IntegratedMode.WEBVIEW, null);
final FrameLayout rootView = new FrameLayout(this);
setContentView(rootView);
rootView.setBackgroundColor(0xffffffff);
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
webview.onRootViewGlobalLayout(rootView);
}
});
// 设置单页面集成的appid
String appid = ""+System.currentTimeMillis();
// 单页面集成时要加载页面的路径,可以是本地文件路径也可以是网络路径
String _url = this.getIntent().getStringExtra("url");
String url = "file:///android_asset/apps/xxxx/www/dist/html/" + _url;
webview = SDK.createWebview(this, url, appid, new IWebviewStateListener() {
@Override
public Object onCallBack(int pType, Object pArgs) {
switch (pType) {
case IWebviewStateListener.ON_WEBVIEW_READY:
// 准备完毕之后添加webview到显示父View中,设置排版不显示状态,避免显示webview时,html内容排版错乱问题
//((IWebview) pArgs).obtainFrameView().obtainMainView().setVisibility(View.INVISIBLE);
SDK.attach(rootView, ((IWebview) pArgs));
break;
case IWebviewStateListener.ON_PAGE_STARTED:
// 首页面开始加载事件
break;
case IWebviewStateListener.ON_PROGRESS_CHANGED:
// 首页面加载进度变化
break;
case IWebviewStateListener.ON_PAGE_FINISHED:
// 页面加载完毕,设置显示webview
// webview.obtainFrameView().obtainMainView().setVisibility(View.VISIBLE);
break;
}
return null;
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return mEntryProxy.onActivityExecute(this,
ISysEventListener.SysEventType.onCreateOptionMenu, menu);
}
@Override
public void onPause() {
super.onPause();
mEntryProxy.onPause(this);
}
@Override
public void onResume() {
super.onResume();
mEntryProxy.onResume(this);
}
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent.getFlags() != 0x10600000) {// 非点击icon调用activity时才调用newintent事件
mEntryProxy.onNewIntent(this, intent);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mEntryProxy.destroy(this);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
boolean _ret = mEntryProxy.onActivityExecute(this,
ISysEventListener.SysEventType.onKeyDown, new Object[] { keyCode, event });
return _ret ? _ret : super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
boolean _ret = mEntryProxy.onActivityExecute(this,
ISysEventListener.SysEventType.onKeyUp, new Object[] { keyCode, event });
return _ret ? _ret : super.onKeyUp(keyCode, event);
}
@Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
boolean _ret = mEntryProxy.onActivityExecute(this,
ISysEventListener.SysEventType.onKeyLongPress, new Object[] { keyCode, event });
return _ret ? _ret : super.onKeyLongPress(keyCode, event);
}
public void onConfigurationChanged(Configuration newConfig) {
try {
int temp = this.getResources().getConfiguration().orientation;
if (mEntryProxy != null) {
mEntryProxy.onConfigurationChanged(this, temp);
}
super.onConfigurationChanged(newConfig);
} catch (Exception e) {
e.printStackTrace();
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
mEntryProxy.onActivityExecute(this, ISysEventListener.SysEventType.onActivityResult,
new Object[] { requestCode, resultCode, data });
}
}
- H5WebviewController类如下:
> #define kStatusBarHeight 20.f @interface H5WebviewController() { } @end @implementation H5WebviewController
-
(void)loadView
{
[super loadView];
// 获取PDRCore句柄
PDRCore* pCoreHandle = [PDRCore Instance];
if (pCoreHandle != nil)
{
// 设置Core启动方式
// [pCoreHandle startAsWebClient];
//[pCoreHandle start];// 设置拼写Webview将要打开文件的url NSString* pFilePath = [NSString stringWithFormat:@"file://%@/%@%@", [NSBundle mainBundle].bundlePath, @"Pandora/apps/xxxxx/www/dist/html/", self.page]; CGRect StRect = CGRectMake(0, kStatusBarHeight, self.view.frame.size.width, self.view.frame.size.height - kStatusBarHeight); // 使用时间戳来区分 NSString *webViewID = [NSString stringWithFormat:@"%ld", (long)[[NSDate date] timeIntervalSince1970]]; PDRCoreAppFrame *appFrame = [[PDRCoreAppFrame alloc] initWithName:webViewID loadURL:pFilePath frame:StRect]; // 设置webview的Appframe [pCoreHandle.appManager.activeApp.appWindow registerFrame:appFrame]; // 将AppFrame设置为当前View的Subview [self.view addSubview:appFrame];
}
}
@end
12 个评论
要回复文章请先登录或注册
4***@qq.com
j***@163.com
1***@qq.com
逞英雄
6***@qq.com
无言_25
3***@qq.com
逞英雄
hello青峰 (作者)
7***@qq.com