#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.