Метод findViewById(int) не определен для типа new Runnable(){}

#java #android #cordova

#java #Android #кордова

Вопрос:

Я работаю над созданием плагина Phonegap для Android. Когда я добавляю findViewById метод в this.ctx.runOnUiThread(new Runnable() , я получаю ошибку, как указано в названии.

Вот мой код:

 package com.company.msgbox;


import java.io.File;

import org.crossplatform.phonegap.trial.alternativeTo.R;
import org.json.JSONArray;
import org.json.JSONException;

import android.app.AlertDialog;
import android.graphics.Bitmap;
import android.view.View;

import com.phonegap.api.Plugin;
import com.phonegap.api.PluginResu<
import com.phonegap.api.PluginResult.Status;

public class msgbox extends Plugin {

    private static final String SHOW = "show";
    private static final int MSG_INDEX = 0;
    private String msg;

    @Override
    public PluginResult execute(String arg0, final JSONArray arg1, String arg2) {
        if ( arg0.equals(SHOW) ) {
            this.ctx.runOnUiThread(new Runnable() {
                public void run() {
                    // try/catch generated by editor
                    try {
                        msg = arg1.getString(MSG_INDEX);
                    } catch (JSONException e) {
                       // TODO Auto-generated catch block
                       e.printStackTrace();
                    }

                    AlertDialog alertDialog = new AlertDialog.Builder(ctx).create();
                    alertDialog.setTitle("Title");
                    alertDialog.setMessage(msg);
                    alertDialog.show();

                    View content = findViewById(R.id.layoutroot);
                    Bitmap bitmap = content.getDrawingCache();
                    File file = new File("/sdcard/test.png");
                }
            });
        }

        return new PluginResult(Status.OK);
    }

}
  

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

1. Пожалуйста, поработайте над своим отступом. Прямо сейчас код не читается.

2. Я отредактировал отступ, ожидая проверки. Он действительно был нечитаемым

3. Спасибо @Guillaume. Побейте меня тоже этим.

Ответ №1:

Вам нужно вызвать findViewById из класса, в котором фактически есть метод. Обычно рекомендуется обходить действие, из которого вы создаете этот класс. Что-то вроде:

 public class msgbox extends Plugin {
    private static final String SHOW = "show";
    private static final int MSG_INDEX = 0;
    private String msg;
    private final Activity parent;

    // constructor
    public msgbox(Activity parent) {
        this.parent = parent;
    }
  

Затем вы можете выполнить:

 parent.findViewById(R.id.layoutroot)
  

Вы создаете свой msgbox изнутри activity, используя:

 msgbox myMsgBox = new msgbox(this);
  

Конечно, для этого R.id.layoutroot компонент должен присутствовать в переданном вами действии.

Если вы не участвуете в activity при создании msgbox, вы можете заменить внедрение конструктора установщиком:

 public void setParent(Activity parent) {
    this.parent = parent;
}
  

Хотя, чтобы иметь возможность использовать findViewById в вашем Runnable , parent должен быть окончательным, поэтому вам придется скопировать его в конечную переменную (очевидно, что внедрение setter не может быть окончательным)

(ПРИМЕЧАНИЕ: Кроме того, ваш класс не использует стандартные соглашения об именовании Java, это сбивает с толку: вызывайте его MsgBox )

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

1. Отлично, это работает, но я точно знаю, что у меня есть что-то вроде: this.context = context; this.parent = (Activity) context; в конструкторе. Есть ли способ получше?

2. Зачем вам это.context = контекст? Нужен ли вам этот.context где-либо еще в вашем классе? Вам нужен только один экземпляр, если вы приведете this.parent к (Activity), он по-прежнему представляет тот же объект

3. Я использую его, потому что мне нужно отправлять данные между действиями. A выполняет B (AsyncTask), затем B возвращает данные в A.