when the .jar contains EventBus module - android

I have to bind a (.jar) file which contains an Eventbus module. When I call it vs reported an exception: XXXActivity has no public methods called onEvent.
but in reality the activity had an onEvent method.
Can help me?
Here is my code!
[Activity(Label = "BaseActivity")]
public class BaseActivity : Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
//EventBus.Default.Register(this);
try
{
JMessageClient.RegisterEventReceiver(this.Application.ApplicationContext);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(" ==ex==" + ex.Message);
}
// Create your application here
}
public void onEventMainThread(CN.Jpush.IM.Android.Api.Event.MessageEvent Event)
{
System.Diagnostics.Debug.WriteLine(" ==1==");
}
...
}
IMRecActivity
[Activity(Label = "IMRecActivity")]
public class IMRecActivity : BaseActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// Create your application here
}
public void onEvent(CN.Jpush.IM.Android.Api.Event.MessageEvent Event)
{
// CN.Jpush.IM.Android.Api.Event.MessageEvent me = (MessageEvent)Event;
CN.Jpush.IM.Android.Api.Model.Message msg = Event.Message;
switch (msg.ContentType.ToString())
{
case "text":
TextContent textContent = (TextContent)msg.Content;
System.Diagnostics.Debug.WriteLine(" ==JMessage OnEvent==" + textContent.Text);
break;
default:
System.Diagnostics.Debug.WriteLine(" ==JMessage OnEvent==" + msg.Content);
break;
}
System.Diagnostics.Debug.WriteLine(" ==JMessage OnEvent==");
}
}
JMessageClient.RegisterEventReceiver(this.Application.ApplicationContext); this used to register an EventBus in the .JAR.With the code,you can see that I have declare onEvent method,but it not working.
By the way,I already uesed a tool like jd-gui to see how it work.
Here is the way to download the .JAR file:
https://www.jpush.cn/downloads/sdk/android/
The Official website,which is a Chinese website.
https://www.jpush.cn/common/products

I would recommend investigating the respective .jar using a tool like jd-gui(http://jd.benow.ca/) to see what the expected method visibility is. You can then use respective Metadata fixes to resolve any issues you find there after the generated binding is created.
I've created a generic guide to help out with this task in which you can look into:
https://gist.github.com/JonDouglas/dda6d8ace7d071b0e8cb

Related

two build types - duplicate code. Not good solution

Android Studio 3.4
I have the next activity:
public class CartActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cart);
someCommonMethod()
}
private void someCommonMethod() {
// some code
}
}
Now I have 2 build types: debug and release.
In debug I add method someDebugMethod() to activity
public class CartActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cart);
someCommonMethod()
someDebugMethod()
}
private void someCommonMethod() {
// some code
}
private void someDebugMethod() {
// some debug code
}
}
In release I add method someReleaseMethod() to activity
public class CartActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cart);
someCommonMethod()
someReleaseMethod()
}
private void someCommonMethod() {
// some code
}
private void someReleaseMethod() {
// some debug code
}
}
I read official documentation
and now project's stucture is:
app\src\debug\java\com\myproject\CartActivity.java
app\src\release\java\com\myproject\CartActivity.java
I remove CartActivity.java from app\src\main\java.
So, as a result, I have two files CartActivity.java.
Nice.
And now when I start the app in debug build type then runCartActivity in debug folder.
And when I start the app in release build type then runCartActivity in release folder.
Nice. It's work fine.
But suppose now I need to update the common method someCommonMethod(). This method used in both build types.
As a result, I need to update TWICE this method. First in app\src\debug\java\com\myproject\CartActivity.java and
then update same method with same code in app\src\release\java\com\myproject\CartActivity.java
So I think this is not good.
Because this is duplicate code. I need to copy & paste EVERY time in TWO files when update method someCommonMethod().
It's really bad.
How to avoid this duplicate code?
The ideal approach is when in CartActivity.java has only delta.
In app\src\debug\java\com\myproject\CartActivity.java has ONLY method someDebugMethod()
In app\src\release\java\com\myproject\CartActivity.java has ONLY method someReleaseMethod()
and common code is in app\src\main\java\com\myproject\CartActivity.java
Is it possible?
P.S. Suppose I have 3 build types.
As result, I need to update same code in three files. It's really not good.
Just create a CommonCartActivity in
app\src\main\java\com\myproject\CommonCartActivity.java
Then extend the class overriding the methods in the flavor implementations.
public class CartActivity extends CommonCartActivity {
protected void someCommonMethod() {
// some code
}
}
In this way CartActivity just inherits from CommonCartActivity with nothing else, duplicated in two flavors.
I think you do not need to complicate the structure of the project. Just use the real-time check.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cart);
someCommonMethod();
if(BuildConfig.DEBUG){
someDebugMethod();
}else{
someReleaseMethod();
}
}
private void someCommonMethod() {
// some code
}
private void someDebugMethod() {
// some debug code
}
private void someReleaseMethod() {
// some release code
}
But, if you need to separate the code, try using one activity, but create a new class (for example, Fork) in two copies for release and debug. Create an instance of the class in the activity. In this class there will be a doMetnod() which will have the necessary code depending on the type of project. So you avoid duplication of the activity code.

Visual Studio / Xamarin OnClickListener

I'm new to programming, so I apologise if this is a stupid question!
I'm building an app in VS15/Xamarin, and am trying to set an onClickListener, however it keep stelling me there is an error "The type name 'OnClickListener' does not exist in the type 'View'".
I've tried a number of solutions, but clearly I'm missing something!
This is my code:
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
namespace MyStory
{
[Activity(Label = "MyStory", MainLauncher = true, Icon = "#drawable/Books")]
public class MainActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
Button btn_Short = FindViewById<Button>(Resource.Id.btn_Short);
Button btn_Flash = FindViewById<Button>(Resource.Id.btn_Flash);
Button btn_Poet = FindViewById<Button>(Resource.Id.btn_Poet);
Button btn_About = FindViewById<Button>(Resource.Id.btn_About);
btn_About.SetOnClickListener(new View.OnclickListener())
{
#override
public void onClick(View v)
{
startActivity(new Intent(MainActivity.this, About.class));
}
}
}
}
}
This is what the screen looks like:
screenshot
C# is not java.Try something like this:
btn_About.Click += myCustomClick;
Then outside your oncreate:
public void myCustomClick(object o, EventArgs e) {
//handle click here
}
But check the syntax.
If you want it your way you should make your activity implement View.IOnClickListener like this:
public class MainActivity: Activity, View.IOnClickListener
{
//code here
}
Question was asked very long ago but I found it and so may others. Hope this helps somebody.
Xamarin has its newances and using += EventHandler has its dangers. Firstly you must be sure to unregister this handler at the end of the object's lifecycle as otherwise it will cause memory leaks. Using Androids ClickListener is really a better solution. In Xamarin you can do something like this
public class TEditClickListener : Java.Lang.Object, View.IOnClickListener
{
private RelayCommand _command;
public TEditClickListener(RelayCommand command)
{
_command = command;
}
public void OnClick(View v)
{
_command?.Execute(null);
}
}
and then instantiate this class and use View.SetOnClickListener method to register it. This way there surely won't be memory leaks.

How onNewIntent() of Activity called from Unity

I am working on unity android project.
I have called the android side methods from unity like this
AndroidJavaObject aObj = new AndroidJavaObject("com.mypackage.UnityBridge",param1,param2);
aObj.Call("callme");
And on Android side
public class UnityBridge{
public UnityBridge(final String param1, final int param2) {
activity = UnityPlayer.currentActivity;
this.param1= param1;
this.param2= param2;
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
// INITIALIZATION OF ANDROID CLASS CONSTRUCTOR HERE
}
});
}
public void callme() {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
if(obj!= null)
{
// ANDROID METHOD CALL HERE
}
}
});
}
This much is working perfectly.
If I want to call Activity specific methods like onPause(), onResume(), so there is a method in unity to do so.
void OnApplicationPause(bool pauseStatus) {
// HERE I CAN CALL activity specific **onPause()** and **onResume()** based on pauseStatus
}
Is there anything in unity from which I can give call to onNewIntent(Intent i) of Android. If not then how is it possible to call onNewIntent()
Please help to resolve this.
I wrote a post how this problem can be solved without overriding Unity activity (its about onActivityResult but the principle is the same): https://medium.com/#tarasleskiv/unity-android-plugins-and-onactivityresult-callback-abef4b6bbc87#.6d7sl8z81
Basically you create a custom empty activity and start it just to receive these callbacks and finish it immediately after that.
Check also this post about how to create activity for onNewIntent callback: https://blog.getsocial.im/android-unity-app-and-the-intent-issue/
Here is the example code of the intermediate activity yo have to create:
public class MyDeepLinkingActivity extends Activity
{
private static String TAG = "GetSocial GetSocialDeepLinkingActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
Log.v(TAG, "Forward the intent");
// Do with intent what you need to
Log.v(TAG, "Returning to main activity");
//start main activity
Intent newIntent = new Intent(this, getMainActivityClass());
this.startActivity(newIntent);
finish();
}
private Class<?> getMainActivityClass() {
String packageName = this.getPackageName();
Intent launchIntent = this.getPackageManager().getLaunchIntentForPackage(packageName);
try {
return Class.forName(launchIntent.getComponent().getClassName());
} catch (Exception e) {
Log.e(TAG, "Unable to find Main Activity Class");
return null;
}
}
}
Looks like there is no built it way to get onNewIntent callback in Unity. However i can suggest to export google android project from unity and override this method in main unity activity
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
//some code
}
Or you can create android plugin with your own activity which extends unity activity, but keep in mind that some plugins could stop working if you do this.

social auth in android nullpointerexception while signout from facebook

I am using social auth library for sharing and login with social media in android app.
I have logged in and authorize successfully with facebook.
But when I try to signout app crashed with nullpointer exception
adapter.signOut(getActivity(), Provider.FACEBOOK.toString());
Getting below error:
05-09 10:24:23.010: E/AndroidRuntime(19998): java.lang.NullPointerException
05-09 10:24:23.010: E/AndroidRuntime(19998): at org.brickred.socialauth.android.SocialAuthAdapter.signOut(SocialAuthAdapter.java:797)
I am using latest version. socialauth-4.4.jar and socialauth-android-3.2.jar
Please make sure to call from activity. Getactivity() from fragment not working after calling method from activity like this will work adapter.signOut(this, Provider.FACEBOOK);
I had a similar problem, this solution works for me:
https://code.google.com/p/socialauth-android/issues/detail?id=108#c16
basically there is a bug in the log out function, you have to log in before log out, otherwise you may get an NPE. the solution above is create a new SocialAuthManager when necessary.
I suggest to import that source code as a java module instead of using the jar file, so you can fix something by yourself, like change the dialog title text, etc...
In signOut function put these lines,
if (providerName != null) {
if (socialAuthManager == null) {
socialAuthManager = new SocialAuthManager();
try {
loadConfig(ctx);
} catch (Exception e) {
Log.d(" SocialAuthAdapter ", "Could not load configuration");
}
}
before
if (socialAuthManager.getConnectedProvidersIds().contains(providerName)) socialAuthManager.disconnectProvider(providerName);
This has solved the issue for me for now, in the class where you would like to sign out instantiate a new adapter if the application-wide adapter is null
//My Activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
//Get the currently available adapter
myApp = (MyApplication) getApplication();
adapter = myApp.getSocialAuthAdapter();
//Adapter initialization if null
if (adapter==null){
adapter = new SocialAuthAdapter(new ResponseListener());
}
}
//ResponseListener Class
public final class ResponseListener implements DialogListener {
#Override
public void onComplete(Bundle values) {
String providerName = values.getString(SocialAuthAdapter.PROVIDER);
// Set a application wide reference to the social adapter here
myApp = (MyApplication) getApplication();
myApp.setSocialAuthAdapter(adapter);
}
#Override
public void onError(SocialAuthError error) {
Log.d("Custom-UI", "Error");
error.printStackTrace();
}
#Override
public void onCancel() {
Log.d("Custom-UI", "Cancelled");
}
#Override
public void onBack() {
Log.d("Custom-UI", "Dialog Closed by pressing Back Key");
}
}
//Code for application class
public class MyApplication extends Application {
// SocialAuth Component
private SocialAuthAdapter socialAuthAdpater;
public SocialAuthAdapter getSocialAuthAdapter() {
return socialAuthAdpater;
}
public void setSocialAuthAdapter(SocialAuthAdapter socialAuthAdapter) {
this.socialAuthAdpater = socialAuthAdapter;
}

Creating AspectJ project for Android

I want to create project that reacts to OnCreate() method.
So, for example, I have activity
public class MainActivity extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
//do something
}
}
And i want my AspectJ class to do something before and after OnCreate method call.
public aspect onCreate
{
pointcut captureOnCreate() : (execution(* onCreate(Bundle)));
before(): captureOnCreate()
{
System.out.println("Aspect BEFORE called");
}
after(): captureOnCreate()
{
System.out.println("Aspect AFTER called");
}
}
I tried to convert project to AspectJ and run it as Android application project, but it doesn't work. What is wrong?
SOLVED
Solved it myself.
In Eclipse AspectJ tools -> Inpath -> Add External JARs and link it to aspectjrt.jar file.
And executoin looks like that:
execution(* onCreate(*))&& !within(com.xxx.automation.onCreate);

Categories

Resources