0

I'm trying to call a method within an activity from another class (BaseExpandableListAdapter). The method in the activity starts a service and calls the bindService(,,) method. However the bindService method always returns false. I've checked other similar posts but none of them fixed my problem. Any comment is greatly appreciated.

Here is the BaseExpendableListAdapter class in which I call the method in the activity:

class myExpandableListAdapter extends BaseExpandableListAdapter {
        private Context _context;
    private List<String> _listDataHeader; // header titles
    // child data in format of header title, child title
    private HashMap<String, String> _listDataChild;
    private TextView myroutes_distance=null;
    private TextView myroutes_time=null;
    private TextView myroutes_speed=null;


    public myExpandableListAdapter(Context context, List<String> listDataHeader,
            HashMap<String, String> listChildData ) {
        this._context = context;
        this._listDataHeader = listDataHeader;
        this._listDataChild = listChildData;

    }

 @Override
        public View getChildView(int groupPosition, final int childPosition,
                boolean isLastChild, View convertView, final ViewGroup parent) {



          MyActivity myactivity = new MyActivity(); 
        myactivity.continue(_context.getApplicationContext()); // continue is the method that I'm calling which is within the activity

}

And here is the Activity with the continue method:

public class MyActivity extends FragmentActivity implements
 MyService.Callbacks{

boolean isBound = false;

@Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

}

public void continue(Context ctx){

        current_intent = new Intent(ctx.getApplicationContext(), MyService.class);

        ctx.getApplicationContext().startService(current_intent); // This method works fine.
    isBound = ctx.getApplicationContext().bindService(current_intent, mConnection, Context.BIND_AUTO_CREATE); // Here is where I have problem. isBound is always false.

 }
    public ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,IBinder service) {
//            
            Myservice.LocalBinder binder = (MyService.LocalBinder) service; 
            myservice = binder.getServiceInstance(); //Get instance of your service! 
            myservice.registerClient(MyActivity.this); //Activity register in the service as client for callabcks! 



           }
}

public void setup(){

current_intent = new Intent(MyActivity.this, MyService.class);

            startService(current_intent); 
        isBound = bindService(current_intent, mConnection, Context.BIND_AUTO_CREATE); 

// both startService and bindService methods work fine here. 


}
}

Please note that I'm using similar commands in the setup() method and it works just fine, but when I'm using bindservice() method in the continue() method the binding fails.

vmontazeri
  • 393
  • 2
  • 20
  • Why did you instantiated the MainActivity in getChildView()? – user Sep 12 '15 at 15:25
  • Well because otherwise, I could not refer to the continue method in MyActivity from another activity. – vmontazeri Sep 12 '15 at 15:29
  • 1
    First, you shouldn't be calling that method from other activities, in the adapter you have a reference to the activity, it's the `_context`. Secondly, you should **never** instantiate activities on your own. – user Sep 12 '15 at 15:32
  • So what do you think I should do? I need to start the service from the MyActivity class and the process starts from the myExpandableListAdapter class. Sorry if my question is vague! – vmontazeri Sep 12 '15 at 15:40
  • Maybe a LocalBroadCastManager? – vmontazeri Sep 12 '15 at 15:42
  • It's not clear at all what you're trying to do. You should start the service in the onCreate method of the Activity(definitely not in getChildView() as that method will be called a lot of times). After you bind to the service you can comunicate with it in various ways(one being the LocalBroadcastmanager that you mentioned). – user Sep 12 '15 at 16:25

1 Answers1

1

Well After the response I got from @Luksprog, I realized that the reason bindService method returns false, is because I was instantiating the MainActivity class from another class, which is not a good idea! Instead, I can call the continue() method with a LocalBroadcastManager. The solution would be something like this:

class myExpandableListAdapter extends BaseExpandableListAdapter {
        private Context _context;
    private List<String> _listDataHeader; // header titles
    // child data in format of header title, child title
    private HashMap<String, String> _listDataChild;
    private TextView myroutes_distance=null;
    private TextView myroutes_time=null;
    private TextView myroutes_speed=null;


    public myExpandableListAdapter(Context context, List<String> listDataHeader,
            HashMap<String, String> listChildData ) {
        this._context = context;
        this._listDataHeader = listDataHeader;
        this._listDataChild = listChildData;

    }

 @Override
        public View getChildView(int groupPosition, final int childPosition,
                boolean isLastChild, View convertView, final ViewGroup parent) {



         // MyActivity myactivity = new MyActivity(); 
      //  myactivity.continue(_context.getApplicationContext()); // continue //is the method that I'm calling which is within the activity



                  Intent intent = new Intent("intent_tag");

                          intent.putExtra("message", childText);
//                        

                          LocalBroadcastManager.getInstance(_context).sendBroadcast(intent);

}

And in the MainActivity class:

public class MyActivity extends FragmentActivity implements
 MyService.Callbacks{

boolean isBound = false;

@Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
  LocalBroadcastManager.getInstance(this).registerReceiver(myBroadcastReceiver,
              new IntentFilter("intent_tag"));


}

private BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {
      @Override
      public void onReceive(Context context, Intent intent) {
        // Get extra data included in the Intent
        String name = intent.getStringExtra("message");
        continue(name);
      }
    };

public void continue(String input){

         // Process data based on the input string. 
         //
         // Mymethod(input);
        current_intent = new Intent(getApplicationContext(), MyService.class);

        getApplicationContext().startService(current_intent); 

    getApplicationContext().bindService(current_intent, mConnection, Context.BIND_AUTO_CREATE); 

 }
    public ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,IBinder service) {
//            
            isBound=true;
            Myservice.LocalBinder binder = (MyService.LocalBinder) service; 
            myservice = binder.getServiceInstance(); //Get instance of your service! 
            myservice.registerClient(MyActivity.this); //Activity register in the service as client for callabcks! 



           }
}

public void setup(){

current_intent = new Intent(MyActivity.this, MyService.class);

            startService(current_intent); 
        isBound = bindService(current_intent, mConnection, Context.BIND_AUTO_CREATE); 

// both startService and bindService methods work fine here. 


}
}
vmontazeri
  • 393
  • 2
  • 20