runOnUiThread Не определено для класса - PullRequest
14 голосов
/ 03 апреля 2012

Я пытаюсь выдать и предупредить диалог в потоке пользовательского интерфейса из моего фонового потока, но у меня возникают проблемы с неопределенностью runOnUiThread. Я пробовал 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) {
                           }
                        });
                    }
                });

Ответы [ 5 ]

31 голосов
/ 03 апреля 2012

Поскольку 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

13 голосов
/ 02 декабря 2014
Another better approach..

Нет необходимости создавать конструктор для получения Activity.

Просто введите контекст в класс Activity.

((Activity)context).runOnUiThread(new Runnable()
    {
        public void run()
        { 
             Toast.makeText(context, toast, Toast.LENGTH_SHORT).show();
        }
    });
3 голосов
/ 03 апреля 2012

runOnUIThread() - это метод, принадлежащий Activity .. Так что вы не можете вызвать его из потока.

Таким образом, вместо Context возьмите экземпляр Activity в своем конструкторе и вызовите его, используя это .. что-то вроде

activity.runOnUIThread();
1 голос
/ 06 августа 2015

Вы можете расширить свой класс, включив в него Activity как этот

public class YourClass extends Activity {}

Это сделает доступным 'runOnUiThread'.

Также не забудьте импортировать Activity

import android.app.Activity;
1 голос
/ 11 июня 2013

Я нашел более аккуратный и более модульный способ сделать это.Для этого вам необходимо определить Application Context.Если у вас есть это, вы можете вызывать RunOnUIThread из любой библиотеки классов, не имея при этом ссылки на Activity.

Из любого места в вашей библиотеке классов звоните:

Handler handler = new Handler(Application.Context.MainLooper);
handler.Post(() => doStuff());

Пожалуйста, имейте в виду, что это написано на C #, так как я использую MonoDroid, но я считаю, что это очень похоже на Java.Чтобы узнать, как создать ApplicationContext, посмотрите на этот поток

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...