I am getting the error
Exception junit.framework.AssertionFailedError: Please have your activity extend XWalkActivity for shared mode
in android crash reports. I have not been able to get this crash on testing. I have only used XWalkView in my game and not XWalkActivity. The implementation is as shown below.
XWalkView mXWalkView = new XWalkView(context);
MyJavaScriptInterface javaInterface = new MyJavaScriptInterface();
mXWalkView.addJavascriptInterface(javaInterface, "interOps");
mXWalkView.load("javascript:( function () { function createURL(event) { window.interOps.Callback(event.data); }window.addEventListener('message', createURL , false); } ) ()",null);
mXWalkView.load(URL, null);
mXWalkView.setResourceClient(new XWalkResourceClient(mXWalkView) {
#Override
public void onLoadFinished(XWalkView view, String url)
{
super.onLoadFinished(view, url);
}
});
Crash log points to the line
XWalkView mXWalkView = new XWalkView(context);
And I have integrated crosswalk in embedded mode and not shared mode; which is why this crash log is confusing. Can anyone help me figure out why this error is being thrown.
I think the error is from load javascript, i tried to reform the javascript abit:
function messageCallback() { window.addEventListener('message', function(event){window.interOps.Callback(event.data);} , false);}messageCallback();
dunno it it helps, but couldn't hurt to try.
It's possible that you're passing the wrong Context, if you're in the activity class try passing this otherwise try getBaseContext() or getApplicationContext() and see if you get the same error.
I do not know whether it is relevant or not. I had same error, i changed supported architectures to v7a and my application runs without errors.
Try it like this;
mXwalkView = new XWalkView(this, null);
Constructor for Crosswalk runtime.
Public Constructors
XWalkView(Context context, AttributeSet attrs)
Constructor for inflating via XML.
XWalkView(Context context, Activity activity)
Related
I have a WebView in the layout xml of my MainActivity, to which I setWebViewClient(new WebViewClient()), followed by loadUrl(...) in onCreate.
Most of the time the app runs fine and the Web content is displayed correctly.
But in some cases, opening the app causes a crash. I've noticed that it happens when the app scheduled a PendingIntent broadcast with AlarmManager, which triggers a Notification whose contentIntent is a PendingIntent.getActivity set to launch MainActivity.
But it happens only in the case when the user has removed the app from the stack of active apps in the meantime (Notification is visible, not yet clicked, and stack if apps cleared. So, app process probably stopped?).
Seemingly no other system modifications in between (in particular no app/system update, no playing around with user profiles or Chrome app.)
Stack trace:
java.lang.RuntimeException:
at android.webkit.WebViewDelegate.getPackageId (WebViewDelegate.java:164)
at yj.a (PG:16)
at xH.run (PG:14)
at java.lang.Thread.run (Thread.java:764)
Occurs with Android 7.0 thru 9. Also, seems to have started to occur when I upgraded target SDK to 28.
I don't use explicitly a WebViewDelegate. It must be internal system code (hence the obfuscation).
By reading the source code of AOSP, it seems that the WebView fails to retrieve the package to which it belongs -- but why sometimes only!?
Any help appreciated! Thanks.
It has taken weeks of investigation on and off, but I've finally found why I'm seeing this issue. For me, it was just because I'd overridden the getResources() method in my application scope to use the current activity. Something like this:
public class MyApplication extends MultiDexApplication {
private static MyApplication sInstance = null;
private WeakReference<Activity> mCurrentActivity;
public static MyApplication getInstance() {
return sInstance;
}
public void setCurrentActivity(Activity activity) {
mCurrentActivity = new WeakReference<>(activity);
}
public Activity getCurrentActivity() {
return mCurrentActivity == null ? null : mCurrentActivity.get();
}
#Override
public Resources getResources() {
// This is a very BAD thing to do
Activity activity = getCurrentActivity();
if (activity != null) {
return activity.getResources();
}
return super.getResources();
}
}
This was done as a shortcut as I often wanted to get strings that were activity-specific, so I was calling MyApplication.getInstance().getResources().getString(). I now know this was a bad thing to do - removing my override of this method instantly fixed it.
So the key takeaway from this for me is that when the WebView is initialising, it MUST be able to get hold of the application context, so that the resources passed into WebViewDelegate.getPackageId() are at the application level - the activity context isn't enough, and causes this error.
As a side note - I wasn't even trying to add a WebView to my application. I was only actually using the following:
String userAgent = WebSettings.getDefaultUserAgent(this);
I was then passing this value into a custom media player that I'm using. Passing "this" as either application or activity scope always failed, due to my override.
Looking through documentation,you can see that error is thrown when package can't be found.Check your syntax ,package name and try again.
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/webkit/WebViewDelegate.java (Line 164)
/**
* Returns the package id of the given {#code packageName}.
*/
public int getPackageId(Resources resources, String packageName) {
SparseArray<String> packageIdentifiers =
resources.getAssets().getAssignedPackageIdentifiers();
for (int i = 0; i < packageIdentifiers.size(); i++) {
final String name = packageIdentifiers.valueAt(i);
if (packageName.equals(name)) {
return packageIdentifiers.keyAt(i);
}
}
throw new RuntimeException("Package not found: " + packageName);
}
In my app I had used the picasso library but when I integrated in my code then it will show .invalidate(file) by red color . How can solve it?
Please find the below code for more reference:
FutureCallback<File> writeNewFileCallback = new FutureCallback<File>() {
#Override
public void onCompleted(Exception e, File file) {
if (e == null) { // Success
Picasso.with(MyApp.this.getActivity()).invalidate(file);
Transformation transformation = new RoundedTransformationBuilder()
.scaleType(ImageView.ScaleType.FIT_XY)
.borderColor(Color.parseColor("#77e5e5e5"))
.borderWidthDp(2)
.cornerRadiusDp(15)
.oval(false)
.build();}
When change it to :
`Picasso.with(this).invalidate(file);`
"this" will be unknown.
For user interface related calls use the Activity context.
See this explanation by Reto Meier: Using Application context everywhere?
This is simple to solve. Just do,
Picasso.with(getApplicationContext()).invalidate(file);
The with() method takes a Context as parameter, putting this works fine when you are inside an Activity.
But in your case, you are using this inside an anonymous inner class, so this refers to that specific class and not your Context.
Hope it helps.
I'm currently trying to develop an application under Android using Mono.
I'd like to add support for plugins to my application so additional features could be brought to it.
I was able to load simple .dll at runtime in my program, however whenever I try creating a dll implementing both my interface and a custom activity, an exception of type Java.Lang.NoClassDefFoundError is thrown.
There is the class inside the dll code:
[Activity (Label = "Vestiaire")]
public class Vestiaire : Activity, IModule
{
public string Name { get; set; }
public string Version { get; set; }
void OnClickVestiaireButton(object sender, System.EventArgs e)
{
;
}
public void InitVestiaireModule()
{
Run();
}
public Type LaunchActivity ()
{
return typeof(Vestiaire);
}
public void Init()
{
Name = "Vestiaire Module";
Version = "0.1";
}
public void Run()
{
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
}
}
The line responsible for the exception: (from the program core)
LoadedPlugin.Add((IModule)(Activator.CreateInstance(Plugin)));
Things I'm actually wonderring are:
- Is it possible to actually achieve what i'm trying to ?
If yes, help would be apreciated on that problem :P
Otherwise what would be the best alternative ?
Global point is to be able to load a custom menu at runtime loaded from a dll.
Thanks.
i think the key to your problem is that the Activity needs to be registered in you Manifest.xml file.
For Activities in you main app, MonoDroid does this for you - but I don't think this will work for your plugin.
Things you could try are:
putting the Activity in the Manifest yourself (MonoDroid does seem very capable at merging these files)
if that doesn't work, then you could try using a Fragment instead - and loading the Fragment into a custom FragmentActivity in your main app.
I want to create a log file for my Android app. I need this to debug the random crashes of the applications.
I want to create a function which always get called if there is a unhandelled exception. In the log I want the exception message. Is there any event kind mechanism which will get invoked on unhandelled exception in ANdroid?
try to use android Android Acra
Really good thing Please try this.
You can write your own log cat,
when your application is installed on real android device and not connected to Eclipse to get debug details..
Please check Tutorial :Read & Store Log-cat Programmatically in Android
also you may like to check this stack-overflow page I have posted solution code snip and related useful information.
You can use UncaughtExceptionHandler as shown below:
public class UncaughtExceptionHandler implements java.lang.Thread.UncaughtExceptionHandler {
String Tag;
Context myContext;
public UncaughtExceptionHandler(Context context, String TAG) {
Tag = TAG;
myContext = context;
}
public void uncaughtException(Thread thread, Throwable exception) {
StringWriter sw = new StringWriter();
exception.printStackTrace(new PrintWriter(sw));
Logger.appendErrorLog(sw.toString(), Tag);
Intent intent = new Intent(myContext, ForceClose.class);
intent.putExtra(BugReportActivity.STACKTRACE, sw.toString());
myContext.startActivity(intent);
Process.killProcess(Process.myPid());
System.exit(10);
}
}
Call this class in the first activity's onCreate() method:
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(getApplicationContext(),"FirstActivity"));
I'm integrating a custom widget into my project. It uses custom attributes and is crashing Robolectric. From what I gather, custom attributes aren't supported yet. Note: the constructor is "hostile" because it throws exceptions on construction, but I've commented them out for now.
Crash Log
java.lang.RuntimeException: error inflating layout/main
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:106)
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:82)
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:86)
at com.xtremelabs.robolectric.res.ResourceLoader.inflateView(ResourceLoader.java:377)
at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:43)
at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:48)
at android.view.LayoutInflater.inflate(LayoutInflater.java)
at com.xtremelabs.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:101)
at android.app.Activity.setContentView(Activity.java)
at com.blah.MainActivity.onCreate(MainActivity.java:17)
at com.blah.MainActivityTest.setUp(MainActivityTest.java:29)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
Caused by: java.lang.ClassCastException: com.blah.support.shadows.ShadowMultiDirectionSlidingDrawer cannot be cast to com.xtremelabs.robolectric.shadows.ShadowView
at com.xtremelabs.robolectric.Robolectric.shadowOf(Robolectric.java:857)
at com.xtremelabs.robolectric.shadows.ShadowViewGroup.addView(ShadowViewGroup.java:70)
at android.view.ViewGroup.addView(ViewGroup.java)
at com.xtremelabs.robolectric.shadows.ShadowViewGroup.addView(ShadowViewGroup.java:60)
at android.view.ViewGroup.addView(ViewGroup.java)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.addToParent(ViewLoader.java:217)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.create(ViewLoader.java:180)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:150)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:153)
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:102)
... 29 more
I'm trying to work around this issue, because I don't care too much about testing this widget. Basically I want my tests not to crash and to verify that the view element is appearing on the screen.
Someone suggested a hack of placing the java file in a android package, but I'm not sure if it applies in my case. As suggested by this answer, the custom widget lives in package "android" which is parallel to my com.blah structure.
I created a shadow of the widget to get around the hostility issue (but currently I just comment out the exception throwing). Originally I wanted to bypass the work that was being done in the constructor since it relies on attributes that Robolectric isn't reporting correctly. The shadow constructor is getting called, but it continues through normal constructor execution. Is there a way to bypass additional construction?
ShadowClass
#Implements (MultiDirectionSlidingDrawer.class)
public class ShadowMultiDirectionSlidingDrawer
{
public void __constructor__( Context context, AttributeSet attrs )
{
}
public void __constructor__( Context context, AttributeSet attrs, int defStyle )
{
}
}
Custom Test Runner
public class CustomTestRunner extends RobolectricTestRunner
{
public CustomTestRunner( Class<?> testClass ) throws InitializationError
{
super( testClass );
addClassOrPackageToInstrument("android");
}
#Override
protected void bindShadowClasses()
{
super.bindShadowClasses();
Robolectric.bindShadowClass( ShadowMultiDirectionSlidingDrawer.class );
}
}
Is this the right approach to work around the crashes until the testing framework supports this? Am I doing something wrong with my shadow or am I missing something else?
So I solved this a simple way. Instead of inflating the view as part of my main.xml, I put it in a separate layout file. In my Activity's constructor, I inflated the layout in a protected function. In my test class, I extended the class under test and instead of inflating the view element, I used a boolean to track that the functions as called.
MainActivity.java
public class MainActivity extends FragmentActivity
{
#Override
public void onCreate( Bundle savedInstanceState )
{
super.onCreate( savedInstanceState );
setContentView( R.layout.main );
addOptionsShade();
}
protected void addOptionsShade()
{
ViewGroup viewGroup = (ViewGroup) findViewById( R.id.main_view );
View view = getLayoutInflater().inflate( R.layout.options_shade, null );
viewGroup.addView( view );
}
}
MainActivityTest.java
#Test
public void shouldHaveOptionsShade() throws Exception
{
assertTrue( mainActivity.hostileLibraryWasCalled );
}
class TestMainActivity extends MainActivity
{
boolean hostileLibraryWasCalled = false;
#Override
protected void addOptionsShade()
{
hostileLibraryWasCalled = true;
}
}
I removed the shadow class & bindings and put the library back in a sensible place (not in android package).