Как я могу повторно использовать внутренний класс в Java/Android?

Я долгое время (8 лет) разработчик С#, занимающийся небольшим развитием Android. Это первый раз, когда я использовал Java, и у меня небольшие проблемы с изменением моего мышления, когда речь идет о внутренних классах.

Я пытаюсь написать класс, чтобы обернуть API RESTful для выполнения различных вызовов на сервере из одного типа места, например.

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

И я хочу использовать AsyncTask, чтобы получить материал в фоновом режиме.

Итак, один из способов - иметь AsyncTask в 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
 }

}

Я не уверен, что идея callback/delegate работает в Java в любом случае!

Другим способом является использование AsyncTask в Activity и создание APIWrapper, чтобы просто получить данные как рабочий/помощник:

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
    }

 }


}

Может ли кто-нибудь помочь мне сделать правильный выбор?

Ответ 1

Java не имеет что-то вроде делегатов на С#, поэтому ваше первое предложение невозможно как-есть.

Стандартное решение - объявить интерфейс, который может быть передан как обратный вызов:

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

Затем вы можете сделать что-то вроде

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
    }
  }
}

или вы можете использовать анонимный класс:

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
        }
      });
  }}); 

Если вам нужно много разных обратных вызовов, вы можете использовать generics, чтобы избежать объявления большого количества небольших интерфейсов:

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
        }
      });
  }}); 

Ответ 2

Обычный внутренний класс содержит ссылку на объект внешнего класса, поэтому его экземпляр не может быть создан без внешнего класса. Это означает, что внутренние классы нельзя повторно использовать вне внешнего класса.

Анонимные внутренние классы, которые вы используете, не могут быть повторно использованы повторно: они создаются в контексте внешнего метода.

Однако вы можете определить внутренний класс как статический. В этом случае вы можете использовать его везде в своем коде.

Но вы, ваше дело, думаете, что лучшее решение - это то, что вы предложили себе как решение. 2. Просто создайте отдельный класс, чтобы вы могли использовать его из любого места вашего кода.