【问题标题】:runOnUiThread Undefined for ClassrunOnUiThread 未定义类
【发布时间】:2012-04-17 00:51:54
【问题描述】:

我正在尝试从我的后台线程在 UI 线程上抛出和警告对话框,但我遇到了 runOnUiThread 未定义的问题。我尝试过FindLocation.this.runOnUiThread 和runOnUiThread,但似乎都抛出了相同的错误The method runOnUiThread(new Runnable(){}) is undefined for the type new LocationListener(){}(或...the type FindLocation)。任何想法为什么?这是我的 FindLocation.java 类的 sn-p。这是我的主要活动调用的。

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) {
                           }
                        });
                    }
                });

【问题讨论】:

  • 那是因为runOnUiThreadandroid.app.Activity 的方法,而不是java.lang.Thread
  • 射击。有没有办法实现类似的东西?
  • @MartinSykes 不,it doesn't
  • @Martin Sykes 请删除该评论。它具有误导性,因为 Context 无法访问 runOnUIThread()
  • 如果 ctx 是 Activity 的实例,它将具有 runOnUiThread。比我之前的评论更清楚。

标签: java android multithreading dialog


【解决方案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 时您的 Activity 仍然存在

【讨论】:

  • 好的,我可以在 Eclipse 中无错误地实现它,但是当我运行它时,act.runOnUiThread(new Runnable() {...}); 行上出现 NullPointerException 错误。为什么会发生这种情况?会不会和我的弯针有关?
  • 通过在act.runOnUiThread() 之前添加Log.d("Test" + "" + act); 来尝试找出实际的null - 如果不是act,那么问题就在你的Runnable
  • 我想,我刚找到它。当我从 Main Activity 启动线程时,我使用以下语句:new FindLocation(getBaseContext(), null).start(usr_id1); 我不确定要传递什么而不是 null。有任何想法吗?我尝试了thisMainActivity,但都不起作用。
  • 是的,问题就在这里。如果您从活动本身调用它,这应该与this 一起使用。如果调用来自内部类,MainActivity.this 应该可以工作。
  • 获取活动,可以使用getActivity().runOnUiThread(...
【解决方案2】:
Another better approach..

获取Activity无需创建构造函数。

只需将上下文类型转换为 Activity 类。

((Activity)context).runOnUiThread(new Runnable()
    {
        public void run()
        { 
             Toast.makeText(context, toast, Toast.LENGTH_SHORT).show();
        }
    });

【讨论】:

  • 在我的情况下抛出异常:java.lang.ClassCastException: android.app.ContextImpl cannot be cast to android.app.Activity
  • 我发现这个可以解决我的问题:stackoverflow.com/a/23324440/2223942。还有什么方法可以成功使用您的方式吗? @Nepster
【解决方案3】:

runOnUIThread() 是属于Activity 的方法。所以你不能从线程中调用它。

所以不是 Context 而是在其构造函数中获取 Activity 实例并使用它调用它.. 类似

activity.runOnUIThread();

【讨论】:

    【解决方案4】:

    我找到了一种更简洁、更模块化的方法。为此,您需要定义一个Application Context。一旦你有了它,你就可以从任何类库中调用RunOnUIThread,而不必担心引用Activity

    从您的类库调用中的任何位置:

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

    请记住,这是用 C# 编写的,因为我使用 MonoDroid,但我相信它与 Java 非常相似。 关于如何创建 ApplicationContext 看这个thread

    【讨论】:

      【解决方案5】:

      您可以扩展您的类以包含 Activity 像这样

      public class YourClass extends Activity {}
      

      这将使“runOnUiThread”可用。

      还要记得导入Activity

      import android.app.Activity;
      

      【讨论】:

        【解决方案6】:

        我昨天在处理 Java Socket 时也遇到过这种情况。

        1。将您的 Activity 传递给 FindLocation 构造函数

        Activity activity;
        
        public FindLocation(Activity activity) {
            this.activity = activity;
        }
        

        然后使用activity对象调用runOnUIThread()

        this.activity.runOnUiThread(new Runnable() {
            ...
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-02-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-30
          • 2012-05-27
          • 2012-04-04
          • 2016-02-23
          相关资源
          最近更新 更多