Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I reuse an inner class in Java / Android?

I'm a long time (8 years) C# developer dabbling in a little android development. This is the first time I've used Java and am having a little trouble shifting my mindset when it comes to inner classes.

I'm trying to write a class to wrap an RESTful API to execute various calls on the server from one typesafe place, e.g.

string jsonResult = APIWrapper.getItems("category 1");

And I want to use a AsyncTask to get stuff in the background.

So one way is this - have the AsyncTask in the APIWrapper :

class ActivityA extends Activity {

 myButton.setOnClickListener(new OnClickListener() {   
  public void onClick(View v) {

    //get stuff and use the onPostExecute inside the APIWrapper
    new APIWrapper().GetItems("Category A", MyGetItemsCallBack);

  }}); 

 function void MyGetItemsCallBack(String result)
 {
    //render the result in the activity context, in a listview or something
 }

}

I'm not sure the callback / delegate idea works in Java anyway!

The other way is to have the AsyncTask in the Activity and create the APIWrapper to just get the data like a worker / helper:

class ActivityA extends Activity {

 myButton.setOnClickListener(new OnClickListener() {   
  public void onClick(View v) {

    //get stuff and use the onProcessComplete inside the APIWrapper
    new GetItems("Category A");

  }}); 

 class GetItems(String theCategory) extends AsyncTask
 {
    doInBackground()
    {
      return new APIWrapper().GetItems(theCategory);
    }

    onPostExecute(String result)
    {
       //render the result in the activity context, in a listview or something
    }

 }


}

Can anyone help me make the right choice?

like image 621
newcube Avatar asked Oct 27 '12 16:10

newcube


People also ask

How do you create a reusable class in Java?

Like everything in Java, the solution revolves around the class. You reuse code by creating new classes, but instead of creating them from scratch, you use existing classes that someone has already built and debugged. The trick is to use the classes without soiling the existing code.

Is it possible to override a inner classes?

No, you cannot override private methods in Java, private methods are non-virtual in Java and access differently than non-private one. Since method overriding can only be done on derived class and private methods are not accessible in a subclass, you just can not override them.

Can we use same class name again to create a inner class?

In Java, it is possible to define a class within another class, such classes are known as nested classes. They enable you to logically group classes that are only used in one place, thus this increases the use of encapsulation, and creates more readable and maintainable code.


2 Answers

Java doesn't have something like C# delegates, so your first proposal is not possible as-is.

The standard solution is to declare an interface that can be passed as a callback:

public interface MyCallback {
  void gotItems(String data);
}

Then you can do something like

class ActivityA extends Activity {
  myButton.setOnClickListener(new OnClickListener() {   
    public void onClick(View v) {
      //get stuff and use the onPostExecute inside the APIWrapper
      new APIWrapper().getItems("Category A", new MyGetItemsCallBack());
  }}); 

  private class MyGetItemsCallBack implements MyCallback {
    public void gotItems(String result) {
      // bla bla bla
    }
  }
}

or you can use an anonymous class:

class ActivityA extends Activity {
  myButton.setOnClickListener(new OnClickListener() {   
    public void onClick(View v) {
      //get stuff and use the onPostExecute inside the APIWrapper
      new APIWrapper().getItems("Category A", new MyCallback() {
        public void gotItems(String result) {
          // bla bla bla
        }
      });
  }}); 

If you need many different kinds of callbacks you can use generics to avoid having do declare many small interfaces:

interface Callback<T> {
  void run(T arg);
}

class ActivityA extends Activity {
  myButton.setOnClickListener(new OnClickListener() {   
    public void onClick(View v) {
      //get stuff and use the onPostExecute inside the APIWrapper
      new APIWrapper().getItems("Category A", new Callback<String>() {
        public void run(String result) {
          // bla bla bla
        }
      });
  }}); 
like image 182
hmakholm left over Monica Avatar answered Oct 10 '22 09:10

hmakholm left over Monica


Regular inner class holds reference to object of outer class, so its instance cannot be created without outer class. It means that inner classes cannot be re-used from outside the outer class.

Anonymous inner classes you are using cannot be reused for sure: they are created in context of outer method.

You can however define inner class as static. In this case you can use it from everywhere in your code.

But you your case I think that the better solution is what you suggested yourself as a solution 2. Just create separate class, so you will be able to use it from anywhere in your code.

like image 43
AlexR Avatar answered Oct 10 '22 10:10

AlexR