Gomobile android using callbacks - android

I have an library written using go mobile and it should has only one callback but when trying implement it, I get two additional methods.
#Override
public Seq.Ref ref() {
return null;
}
#Override
public void call(int i, Seq seq, Seq seq1) {}
Question is, which is right way to implement callback from go on Android Activity?
Right now i have next:
public class MainActivity extends Activity implements implements Mobile.Callback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
Mobile.Client client = Mobile.New("192.168.2.1", 9000, this);
try {
client.Connect();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void OnMessage(String s) {
Log.e("GO", s);
}
#Override
public Seq.Ref ref() {
return null;
}
#Override
public void call(int i, Seq seq, Seq seq1) {
}
}
Connection is established successfully but on callback to activity i getting:
panic: runtime error: invalid memory address or nil pointer dereference
If someone can help I'll be really appreciate.

What is the Go source you are binding? (The package mobile and Callback interface)
For passing the Java class that implements Go interface type, see the section "Passing target language objects to Go" of
https://godoc.org/golang.org/x/mobile/cmd/gobind
Basically, the generated Java interface type is not meant to be used directly. Instead, the Java class should extends the generated Java interface's Stub class.

Use Mobile.Callback.Stub instead of Mobile.Callback for android
...
Mobile.Client client = Mobile.New("192.168.2.1", 9000, new Callbacks());
...
class Callbacks extends Mobile.Callback.Stub {
#Override
public void OnMessage(String s) {
....
}
}

Related

Dagger listener/interface injection

Hello everyone I've been struggling to understand how to inject a listener to a main activtity with Dagger2, I wonder if what I'm trying to do is possible or even a right move with dagger or should I just let it like it is right now I have read that I need to create another class with the implementation of that interface but is not possible(or recommended) to inject on the mainactivity?, thanks in advance to anyone who can help me, I have everything in short as follows:
//////////////////////////////////////MainActivity.class//////////////////////////////////////
public class MainActivity extends AppCompatActivity implements CustomListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//this is the object I want to inject in Dagger
LongProcess longProcess = new LongProcess(this);
longProcess.longRunningProcess();
}
#Override
public void onProcessStarted() {
Log.i(TAG, "onProcessStarted: CALLBACK!");
}
#Override
public void onProcessFailed() {
Log.e(TAG, "onProcessFailed: CALLBACK!");
}}
//////////////////////////////////////LongProcess.class//////////////////////////////////////
public class LongProcess {
private CustomListener customListener;
public LongProcess(CustomListener customListener) {
this.customListener = customListener;
}
public void longRunningProcess() {
try {
//some long process started...
customListener.onProcessStarted();
} catch (Exception e) {
//some long process failed...
customListener.onProcessFailed();
}
}
}
//////////////////////////////////////interface.java//////////////////////////////////////
public interface CustomListener {
void onProcessStarted();
void onProcessFailed();
}
You can take a look at Assisted Injection for this use case: https://dagger.dev/dev-guide/assisted-injection

Not understanding why AsyncTask is giving me an incompatible type

I'm trying to get access into my database in the background so that i don't lock the threads and get an error, so i read i should use AsyncTask. from what i read up on it takes uses 3 data types. The data type it takes in, the data type it processes, and the return data type. so here im making a step tracker and want to access my database to get something by id, so i call my repository and pass in the database i'm using and the id i want to find
cStep = stepRepository.getStepById(stepDatabase,0);
and this here is my repository class and the AsyncTask within it
> public class StepRepository implements IStepDataSource {
private IStepDataSource mLocalDataSource;
private static StepRepository mInstance;
public StepRepository(IStepDataSource mLocalDataSource) {
this.mLocalDataSource = mLocalDataSource;
}
public static StepRepository getInstance(IStepDataSource mLocalDataSource){
if(mInstance == null)
mInstance = new StepRepository(mLocalDataSource);
return mInstance;
}
#Override
public Flowable<List<Step>> getAllSteps() {
return mLocalDataSource.getAllSteps();
}
#Override
public Step getStepById(StepDatabase db, int userId) {
return new getAsyncTask(db).execute(userId);
}
private static class getAsyncTask extends AsyncTask<Integer, Void, Step> {
getAsyncTask(StepDatabase db) {
this.db = db;
}
#Override
protected Step doInBackground(Integer... params) {
StepDao dao = db.stepDao();
return dao.getStepById(params[0]);
}
#Override
protected void onPostExecute(Step step) {
}
}
#Override
public void insertStep(Step... steps) {
mLocalDataSource.insertStep(steps);
}
#Override
public void updateStep(Step... steps) {
mLocalDataSource.updateStep(steps);
}
#Override
public void deleteStep(Step step) {
mLocalDataSource.deleteStep(step);
}
}
im not getting why getUserByid is giving me imcopatible type since AsyncTask takes in and interger and returns a steps which is what i want??
btw if its any help this is the IStepDataSource my repository implements
public interface IStepDataSource {
Flowable<List<Step>> getAllSteps();
Step getStepById(StepDatabase db, int userId);
void insertStep(Step... steps);
void updateStep(Step... steps);
void deleteStep(Step step);
}
The execute() method of AsyncTask returns void and your are attempting to return a void from a method declared as returning Step. It's probably best to get the AsyncTask out of the getStepById() method and instead use an AsyncTask where you invoke getStepById(). I think you're assuming that execute() blocks until the task is complete and that is incorrect. If this were the case, there'd be no point to using AsyncTask. execute() returns immediately and onPostExecute(Step step) is where the results should be processed/displayed/whatever.

How to translate event driven code?

I'm mostly C# developer and I'm recently working on some Android project. I have to implement some custom written events in Android, but I'm not sure how to do that.
I wrote a C# code for what I want to do, so if anyone can help me with translating it into Android code, that would be appreciated.
I need to have a custom function (event), placed at MySecondClass, which can be triggered from MyFirstClass.
For example, we have the class:
private class MyFirstClass
{
private event EventHandler<MyCustomEventArgs> _myCustomEvent;
public event EventHandler<MyCustomEventArgs> MyCustomEvent
{
add { _myCustomEvent += value; }
remove { _myCustomEvent -= value; }
}
public void Initialize()
{
MySecondClass myObjectSecondClass = new MySecondClass();
this.MyCustomEvent += myObjectSecondClass.SomeMethodSecondClass;
}
public void SomeMethodFirstClass(int index)
{
//here we will trigger the event with some custom values
EventsHelper.Fire(this.MyCustomEvent, this, new MyCustomEventArgs(index));
}
}
The MyCustomEventArgs is defined as:
public class MyCustomEventArgs : EventArgs
{
public int index;
public MyCustomEventArgs(int indexVal)
{
index = indexVal;
}
}
And the the second class is defined as:
private class MySecondClass
{
public void SomeMethodSecondClass(object sender, MyCustomEventArgs e)
{
//body of the method
//we can use e.index here in the calculations
}
}
So I'm not sure how to handle with these "Event" related commends in Android.
Its all interfaces in java. No fancy complicated key word here :)
There should be an interface which the second class implements.
public interface EventHandler{
void onEventFired(EventParams e);
}
public class MyFirstClass{
EventHandler eventHandler;
public void initialize(){
eventHandler = new MySecondClass();
}
public void method(){
EventParams eventParams = new EventParams();
//fire event here
eventHandler.onEventFired(eventParams);
}
}
public class MySecondClass implements EventHandler{
#Overrride
void onEventFired(EventParams e){
//handle event here
}
}
I hope you get the idea

Android Service and its engine

I have one doubt about using services. I have a service that initializes an object, is it a bad practice to pass an instance of the service to the object so it can be used for that object? A simplified object would be:
public class MyService extends Service {
MyObject myObject = new MyObject(this);
...
}
public MyObject {
private MyService myService;
public MyObject(MyService myService) {
this.myService = myService;
}
...
private void exampleMethod() {
myService.method();
}
}
What do you think? Is it a bad practice? How could I solve that issue without passing the service's instance?
The fact is that I want to split the code in two classes because the features are different, the websocket is connected from the service class, but the methods to parse/send events through the websocket are in the second class. I want to do this way in order to avoid having one class with 2000 lines of code, and by splitting the code by features. The service handles the websocket connection, while the other class handles the other features. As everything is asynchronous, the second class needs an instance of the service class. For instance: if an error is received and parsed (on the second class), this second class must call the service class to update its status and do a reconnection.
EDIT:
I'm thinking about implementing the following solution:
public class MyService extends Service {
MyObject myObject = new MyObject() {
protected void onSuccess() {
...
}
};
...
}
public abstract class MyObject {
public MyObject() {
}
protected abstract void onSuccess();
...
private void exampleMethod() {
...
onSuccess()
}
}
The more I think about it, the better solution I think it is. What do you think?
Thank you very much in advance!
This makes no sense at all. I suggest you to use a interface if you need to pass a callback to a dao (the websocket controller). The thing is that you should use your service to implement your websocket controller.
Please add the websocket code, so we can suggest more changes.
EDIT:
public interface onGetData {
public void onSuccess(Object response) // here you pass the obj type you need in your service
public void onError(Object error) // same, but if things fail
}
public class MyService extends Service implements onGetData {
#Override
public void OnCreate() {
MyObject myObject = new MyObject(this);
}
#Override
public void onSuccess(Object response) {
}
#Override
public void onError(Object error) {
}
}
public MyObject {
private OnGetData onGetData ;
public MyObject(OnGetData onGetData) {
this.onGetData = onGetData;
}
private void onRequestSuccess(Object response) {
onGetData.onSuccess(response)
}
private void onRequestError(Object error) {
onGetData.onError(error)
}
}

Android: call method of overrided class from library

In this example I have an app which is playing mp3 songs, but there are different license checks by companies.
So in my library I have 3 files:
public interface UserCheckerInterface {
public void appIsEnabled(boolean result);
}
public class UserChecker {
public static void appisEnabled(final UserCheckerInterface userCheckerInterface) {
userCheckerInterface.appIsEnabled(true);
}
}
public class MainActivity extends Activity {
#Override
public void onCreate(final Bundle savedInstanceState) {
....
UserChecker.appisEnabled(new UserCheckerInterface(
#Override
public void appisEnabled(final boolean result) {
Toast.makeText(getApplicationContext(), "" + result, 0).show();
}
));
}
}
I would like override the UserChecker.appisEnabled method in my app which is using this library, but I don't know how.
I am not sure whether I have understood your question, if I did, than you simply have to implement your interface by writing
public class UserChecker implements UserCheckerInterface{
#Override
public static void appisEnabled(final UserCheckerInterface userCheckerInterface) {
userCheckerInterface.appIsEnabled(true);
}
}
Once you do that, then the IDE will show you an error IF you have not implemented the method; which is not the case in this scenario.

Categories

Resources