Android Phonegap和碎片
我试图在我的片段中实现Phonegap CordovaWebView,但它不起作用 我的布局如下所示(cordovawebview.xml): 也许有人有一些关于如何修复它的提示。我总是会犯这样的错误:Android Phonegap和碎片,android,android-layout,cordova,android-fragments,Android,Android Layout,Cordova,Android Fragments,我试图在我的片段中实现Phonegap CordovaWebView,但它不起作用 我的布局如下所示(cordovawebview.xml): 也许有人有一些关于如何修复它的提示。我总是会犯这样的错误: 10-25 15:52:02.839: ERROR/AndroidRuntime(2878): FATAL EXCEPTION: main android.view.InflateException: Binary XML file line #21: Error inflating c
10-25 15:52:02.839: ERROR/AndroidRuntime(2878): FATAL EXCEPTION: main
android.view.InflateException: Binary XML file line #21: Error inflating class org.apache.cordova.CordovaWebView
at android.view.LayoutInflater.createView(LayoutInflater.java:613)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
at com.advantageframework.tabs.fragments.SampleFragmentA.onCreateView(SampleFragmentA.java:81)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:871)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1083)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:635)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1431)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:420)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
at android.view.LayoutInflater.createView(LayoutInflater.java:587)
... 19 more
Caused by: java.lang.NullPointerException
at org.apache.cordova.CordovaWebView.loadConfiguration(CordovaWebView.java:643)
at org.apache.cordova.CordovaWebView.<init>(CordovaWebView.java:131)
... 22 more
10-25 15:52:02.839:错误/AndroidRuntime(2878):致命异常:main
android.view.InflateException:二进制XML文件行#21:膨胀类org.apache.cordova.CordovaWebView时出错
在android.view.LayoutInflater.createView中(LayoutInflater.java:613)
位于android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
位于android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
在android.view.LayoutInflater.充气(LayoutInflater.java:489)
在android.view.LayoutInflater.inflate(LayoutInflater.java:396)
位于com.advantageframework.tabs.fragments.SampleFragmentA.onCreateView(SampleFragmentA.java:81)
位于android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:871)
位于android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1083)
位于android.support.v4.app.BackStackRecord.run(BackStackRecord.java:635)
位于android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1431)
位于android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:420)
位于android.os.Handler.handleCallback(Handler.java:615)
位于android.os.Handler.dispatchMessage(Handler.java:92)
位于android.os.Looper.loop(Looper.java:137)
位于android.app.ActivityThread.main(ActivityThread.java:4745)
位于java.lang.reflect.Method.Invokenactive(本机方法)
位于java.lang.reflect.Method.invoke(Method.java:511)
在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)上
位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
在dalvik.system.NativeStart.main(本机方法)
原因:java.lang.reflect.InvocationTargetException
位于java.lang.reflect.Constructor.constructNative(本机方法)
位于java.lang.reflect.Constructor.newInstance(Constructor.java:417)
位于android.view.LayoutInflater.createView(LayoutInflater.java:587)
... 还有19个
原因:java.lang.NullPointerException
位于org.apache.cordova.CordovaWebView.loadConfiguration(CordovaWebView.java:643)
位于org.apache.cordova.CordovaWebView(CordovaWebView.java:131)
... 还有22个
我找到了答案。如果查看logcat,就会发现它试图将上下文转换为CordovaInterface。上下文就是活动。它失败了。你可能把碎片做成了一个接口。我就是这么做的。您必须使活动成为CordovaInterface,并从活动将事件(onMessage,…)转发到片段
这是我的活动(删除一些内容以使其更简单)。我有一个非常接近这个的东西,效果非常好。之后,您仍然会遇到一些较小的问题,但这些问题很容易解决
public class MyCordovaActivity extends SherlockFragmentActivity implements
CordovaInterface {
private final ExecutorService mThreadPool = Executors.newCachedThreadPool();
private CordovaPlugin mActivityResultCallback;
private CordovaFragment mFragment;
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.nbu_web_activity);
mFragment = new CordovaFragment();
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment, mFragment)
.commit();
// TODO this value you could pass to the activity with a intent extra
// or allow to do this through a seperate function, ...
String url = "http://....";
mFragment.loadUrl(url);
}
@Override
protected void onNewIntent(final Intent intent) {
super.onNewIntent(intent);
NBUGapFragment fragment = getCordovaFragment();
if (fragment != null && fragment.appView != null) {
fragment.appView.onNewIntent(intent);
}
}
@Override
public void onBackPressed() {
NBUGapFragment fragment = getCordovaFragment();
if (fragment == null || !fragment.onBackPressed()) {
super.onBackPressed();
}
}
@Override
public void cancelLoadUrl() {
getCordovaFragment().cancelLoadUrl();
}
@Override
public Activity getActivity() {
return this;
}
@Override
public Context getContext() {
return this;
}
@Override
public ExecutorService getThreadPool() {
return mThreadPool;
}
@Override
public Object onMessage(final String id, final Object data) {
return getCordovaFragment().onMessage(id, data);
}
@Override
public void setActivityResultCallback(final CordovaPlugin plugin) {
mActivityResultCallback = plugin;
}
@Override
public void startActivityForResult(final CordovaPlugin plugin, final Intent intent,
final int requestCode) {
mActivityResultCallback = plugin;
startActivityForResult(intent, requestCode);
}
@Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
if (mActivityResultCallback != null) {
mActivityResultCallback.onActivityResult(requestCode, resultCode, intent);
} else {
super.onActivityResult(requestCode, resultCode, intent);
}
}
private CordovaFragment getCordovaFragment() {
// the CordovaFragment is the one implementing CordovaInterface
return mFragment;
}
}
@覆盖
CreateView上的公共视图(布局、充气机、视图组容器、捆绑包保存状态){
视图v=充气机。充气(R.layout.cordovawebview,container,false);//cordovawebview假设充气机的上下文(在本例中为主活动)实现CordovaInterface。没有接口传递单独的对象(上下文和CordovaInterface对象)通过inflater,您应该创建代理上下文,其中包含两个对象和每个对象的委托方法调用
private class CordovaContext extends ContextWrapper implements CordovaInterface
{
CordovaInterface ci;
// Hold two objects. Method call to Context will be proxied by ContextWrapper, so only delegate CordovaInterface.
// You should add/modify when method in CordovaInterface changed
public CordovaContext(Context base, CordovaInterface ci) {
super(base);
this.ci = ci;
}
public void startActivityForResult(CordovaPlugin command,
Intent intent, int requestCode) {
ci.startActivityForResult(command, intent, requestCode);
}
public void setActivityResultCallback(CordovaPlugin plugin) {
ci.setActivityResultCallback(plugin);
}
public Activity getActivity() {
return ci.getActivity();
}
public Object onMessage(String id, Object data) {
return ci.onMessage(id, data);
}
public ExecutorService getThreadPool() {
return ci.getThreadPool();
}
}
在Fragment中,创建使用此上下文对象的充气器
LayoutInflater localInflater = inflater.cloneInContext(new CordovaContext(getActivity(), this));
View v = localInflater.inflate(R.layout.cordovawebview, container, false);
你发现问题了吗?只是遇到了同样的问题并开始调查。不幸的是没有。我现在正在使用活动和CordovaInterface。如果你需要一个入口点,请尝试一下。在MainActivity中,你可以将“MainActivity Extendes ActionBarAvtivity”更改为“MainActivity Extendes FragmentActivity”或者SherlockFragmentActivity,如果你需要的话。你能提供一个裸体的代码构造吗?只是为了确定-那太棒了!你也能分享你的CordovaFragment的代码吗?我正试图构建它,但我想我一直无法从getActivity()返回活动如果我实现Cordova接口,则在片段中使用它。@osayilgan:我不确定我是否理解您的问题。基本上,您实现的片段与此类似:@PatrickBoos我知道这个类,当我想在我的活动中使用CordovaWebView时,我也使用它。我基本上要问的是,这个DroidGap类是从Activity扩展而来的,n如果您想在片段中实现CordovaInterface,那么您需要实现getActivity()方法,它也是FragmentActivity中的一个超类。作为旁注。我越是使用片段进行cordova,我就越不喜欢cordova。它完全是为主要用于活动而不是片段而构建的。你最终会遇到很多问题。这个问题现在不会是你的最后一个;-)。但它是可行的。但是需要做很多工作。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.cordovawebview, container, false); // <--- add false parameter
CordovaWebView webView = (CordovaWebView)v.findViewById(R.id.mainView);
return v;
}
private class CordovaContext extends ContextWrapper implements CordovaInterface
{
CordovaInterface ci;
// Hold two objects. Method call to Context will be proxied by ContextWrapper, so only delegate CordovaInterface.
// You should add/modify when method in CordovaInterface changed
public CordovaContext(Context base, CordovaInterface ci) {
super(base);
this.ci = ci;
}
public void startActivityForResult(CordovaPlugin command,
Intent intent, int requestCode) {
ci.startActivityForResult(command, intent, requestCode);
}
public void setActivityResultCallback(CordovaPlugin plugin) {
ci.setActivityResultCallback(plugin);
}
public Activity getActivity() {
return ci.getActivity();
}
public Object onMessage(String id, Object data) {
return ci.onMessage(id, data);
}
public ExecutorService getThreadPool() {
return ci.getThreadPool();
}
}
LayoutInflater localInflater = inflater.cloneInContext(new CordovaContext(getActivity(), this));
View v = localInflater.inflate(R.layout.cordovawebview, container, false);