RunOnUiThread Undefined для класса
Я пытаюсь запустить диалог предупреждения в потоке пользовательского интерфейса из моего фонового потока, но у меня возникают проблемы с runOnUiThread undefined. Я пробовал FindLocation.this.runOnUiThread
и runOnUiThread, но оба, похоже, бросают ту же ошибку The method runOnUiThread(new Runnable(){}) is undefined for the type new LocationListener(){}
(или ...the type FindLocation
). Любые идеи почему? Вот фрагмент моего класса FindLocation.java. Это называется моей основной деятельностью.
public class FindLocation extends Thread {
public boolean inJurisdiction;
public boolean AlertNotice = false;
private LocationManager locManager;
private LocationListener locListener;
Context ctx;
public String userId;
public FindLocation(Context ctx) {
this.ctx = ctx;
}
public void start(String userId) {
this.userId = userId;
super.start();
}
@Override
public void run() {
Looper.prepare();
final String usr = userId;
//get a reference to the LocationManager
locManager = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
//checked to receive updates from the position
locListener = new LocationListener() {
public void onLocationChanged(Location loc) {
String lat = String.valueOf(loc.getLatitude());
String lon = String.valueOf(loc.getLongitude());
Double latitude = loc.getLatitude();
Double longitude = loc.getLongitude();
if (latitude >= 39.15296 && longitude >= -86.547546 && latitude <= 39.184901 && longitude <= -86.504288 || inJurisdiction != false) {
Log.i("Test", "Yes");
inJurisdiction = true;
FindLocation.this.runOnUiThread(new Runnable() { ///****error here****
public void run() {
AlertDialog.Builder alert = new AlertDialog.Builder(ctx);
alert.setTitle("Sent");
alert.setMessage("You will be contacted shortly.");
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
});
}
});
Ответы
Ответ 1
Так как runOnUIThread()
является методом Activity
, вы можете передать ссылку на операцию вызова в конструкторе.
...
Context ctx;
Activity act;
public String userId;
...
public FindLocation(Context ctx, Activity act) {
this.ctx = ctx;
this.act = act;
}
и используйте runOnUIThread()
как
act.runOnUiThread(new Runnable() {...});
Однако я считаю, что это небезопасно, и вам нужно принять меры предосторожности, чтобы убедиться, что ваша активность все еще существует, когда вы вызываете runOnUiThread
Ответ 2
Another better approach..
Не нужно создавать конструктор для получения активности.
Просто создайте контекст для класса Activity.
((Activity)context).runOnUiThread(new Runnable()
{
public void run()
{
Toast.makeText(context, toast, Toast.LENGTH_SHORT).show();
}
});
Ответ 3
runOnUIThread()
- это метод, принадлежащий Activity
.. SO, вы не можете его вызывать из потока.
Итак, вместо контекста возьмите экземпляр Activity в свой конструктор и вызовите его с помощью этого.. что-то вроде
activity.runOnUIThread();
Ответ 4
Я нашел более аккуратный и более модульный способ сделать это. Для этого вам необходимо определить Application Context
. После этого вы можете вызвать RunOnUIThread
из любой библиотеки классов без беспорядка с ссылкой на Activity
.
Из любой точки вашего вызова библиотеки классов:
Handler handler = new Handler(Application.Context.MainLooper);
handler.Post(() => doStuff());
Пожалуйста, имейте в виду, что это написано на С#, поскольку я использую MonoDroid, но я считаю, что он очень похож на Java.
Для того, чтобы создать ApplicationContext, посмотрите thread
Ответ 5
Вы можете расширить свой класс, включив Activity
Как этот
public class YourClass extends Activity {}
Это сделает доступным "runOnUiThread".
Также не забудьте импортировать Activity
import android.app.Activity;