Измените текст TextView из другого класса с помощью интерфейса

#java #android #interface

#Ява #Android #интерфейс

Вопрос:

Я пытаюсь позже сделать некоторые функции utils для использования в большем приложении(загрузка файла с URL, загрузка файла по URL и т. Д.), Поэтому В MainActivity У меня есть только 2 кнопки, которые при нажатии вызывают статические методы из класса Utils. Тем не менее, я хочу, чтобы в MainActivity были некоторые показатели того, как работают методы загрузки/загрузки(подключение, успешность/неудача подключения, процент загрузки и т. Д.), Поэтому я включил в MainActivity текстовое представление, которое покажет это. Я создал интерфейс ICallback, который содержит статус void setConnectionStatus(статус строки), и из класса Utils я использую его для отправки статуса в MainActivity.

Вот некоторые части кода :

 public class MainActivity extends AppCompatActivity implements ICallback {  Button btnDownloadDB, btnUploadDB, btnUploadPics; TextView txtStatus; ProgressBar pb;  @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);   //Initialize stuffs  initViews();   //Setting listeners  btnDownloadDB.setOnClickListener(v -gt; {  txtStatus.setText(R.string.connecting);  pb.setVisibility(View.VISIBLE);  Utils.downloadFile(DOWNLOAD_DB, DB_FILE_NAME);  }); }  @Override public void setConnectionStatus(String status) {  Log.d("MIHAI", status);  txtStatus.setText(status); }  

Интерфейс :

 public interface ICallback { void setConnectionStatus(String status); }  

И класс Utils :

 public class Utils {  static ICallback callback= new MainActivity();  public static void downloadFile(String downloadURL, String fileName) {   IFileTransferClient client = ServiceGenerator.createService(IFileTransferClient.class);  Calllt;ResponseBodygt; responseBodyCall = client.downloadFile(downloadURL);   responseBodyCall.enqueue(new Callbacklt;ResponseBodygt;() {  @Override  public void onResponse(Calllt;ResponseBodygt; call, Responselt;ResponseBodygt; response) {  Log.d("MIHAI", "connection ok");  callback.setConnectionStatus("Connection successful");  }   @Override  public void onFailure(Calllt;ResponseBodygt; call, Throwable t) {  Log.d("MIHAI", "err...fail");  callback.setConnectionStatus("Connection failed. Check internet connection.");  }  }); }  

Проблема появляется в MainActivity, когда я пытаюсь установить текст в TextView txtStatus, получая ошибку с нулевой ссылкой, даже если txtStatus инициализирован методом initViews (). Журналы работают нормально, поэтому я получаю правильный статус в MainActivity. Я попытался снова инициализировать TextView в этой функции, прежде чем отправлять текст, и я получил : «java.lang.Исключение NullPointerException: Попытка вызвать виртуальный метод ‘android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()’ для ссылки на нулевой объект в android.content.ContextWrapper.getApplicationInfo(ContextWrapper.java:183)»

Есть ли какой-нибудь шанс, чтобы это сработало? Спасибо, что прочитали.

С уважением, Михай

Комментарии:

1. Вызвана ли ошибка прослушивателем или методом setConnectionStatus?

Ответ №1:

С вашим решением существует множество проблем, но главная из них-эта строка:

 static ICallback callback= new MainActivity();  

Прежде всего, никогда не держите статическую ссылку на Действие, Фрагмент, Контекст или любые классы, связанные с контекстом. Эти классы либо привязаны к a Context , либо представляют Context собой само по себе. Таким образом, у вас может произойти утечка памяти. Но это другая проблема.

Реальная проблема в вашем коде заключается в том, что new MainActivity() в Utils классе создается совершенно другой экземпляр MainActivity , который не имеет ничего общего с MainActivity тем, что отвечает за отображение вашего пользовательского интерфейса во время выполнения.

Вместо этого вам следует передать экземпляр ICallback функции в качестве аргумента:

 public static void downloadFile(String downloadURL, String fileName, ICallback callback) { ... }  

И убрать static ICallback callback= new MainActivity(); .

Примечание: когда вы передаете объект обратного вызова функции, убедитесь, что при его вызове ваш Activity объект не находится в завершенном состоянии.

Комментарии:

1. Большое спасибо. Сделал то, что вы предложили, и работает. Пожалуйста, скажите мне, какие еще проблемы с решением. Я действительно хочу узнать больше. Спасибо!