【原创】离线打包webapp模式,实现从任意原生app界面跳转到h5的指定页面

> 背景:离线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做出关闭动作】

\n

具体代码:

  • 安卓:在需要的地方调用:
\n
 Intent intent = new Intent( this, WebviewActivity.class);
String _url = "h5page.html";// 此处还可以在url里传递数据
intent.putExtra("url", _url);
this.startActivity(intent);
\n

关键的部分就是那个WebviewActivity.java, 具体见下方代码。

  • 苹果:在需要的地方调用:
\n
H5WebviewController *vc = [[H5WebviewController alloc] init];
vc.page = @"userpage.html?userid=1000011";
[self presentViewController:vc animated: YES completion:nil];// 此处也可以push的方式
\n

关键的部分就是那个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 });
}
}

\n
  • H5WebviewController类如下:
\n
> #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
\n
0 分享 关注
hello青峰

hello青峰 回复 462097637@qq.com

这是5+官方限制的
0 赞 2018-12-14 10:19
735132377@qq.com

735132377@qq.com 回复 784076047@qq.com

[self.view addSubview:appFrame];
将上面这行换成下面的代码:
[pCoreHandle.appManager.activeApp.appWindow showFrame:appFrame];
亲测有效
0 赞 2018-12-05 17:45
784076047@qq.com

784076047@qq.com 回复 462097637@qq.com

我也遇到这个问题,问一下是如何解决的呢?
0 赞 2018-11-25 14:45
462097637@qq.com

462097637@qq.com

原生启动后的一个h5页面无法打开子网页
0 赞 2017-12-26 10:49

要回复文章请先登录注册