【问题标题】:Access variable on one thread from another thread - Android从另一个线程访问一个线程上的变量 - Android
【发布时间】:2013-09-07 02:04:03
【问题描述】:

您好,我已经创建了 Activity。让我们假设 BaseActivity。我在该活动中创建了一个新线程。

实际上,我已经阅读并知道一旦活动在 onConfigurationChange 或其他一些上被破坏并且内存被泄漏,线程就不会被垃圾收集。

有 2 条规则可以解决此问题。

一种将 Thread 类设为静态,另一种是在 onDestroy 中显式停止线程。我两者都做了。

我创建了这个线程来查询内容提供者。所以我设法将 applicationContext 放入 Thread 并开始使用它。但不幸的是,我不能使用我在 OnCreate 中声明的光标,例如“Cursor myCursor;” .我尝试将返回的光标分配给这个 myCursor。它要求我创建一个局部变量。我认为这是活动上下文的问题。

当我得到应用程序上下文时,我想,“我得到了整个应用程序上下文”。但不幸的是没有。我什至搜索并发现我应该得到一个对外部类的 WeakReference。我清楚地了解 WekaReference 但不幸的是,对于我的情况,我不知道如何获得我的外部类的弱引用。 kindle 帮帮我。

我什至尝试将活动上下文传递给 MyThread(BaseActivity.this) 之类的线程构造函数,但我不知道如何在线程中使用它。

public class MediaActivity extends Activity {
ExpandableListView expList ;
ExpandableListAdapter expListAdapter;
List<String> albumHead;
HashMap<String, List<String>> albumChild;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_media);

    ExpandableListView expList = (ExpandableListView)findViewById(R.id.mediaList);

    Cursor albumCursor;
    AlbumThread albumThread = new AlbumThread();
    albumThread.start();
}

private static class AlbumThread extends Thread{
    Context appContext = MediaApp.getAppContext();
    Context mediaActivity;

    public AlbumThread() {
        super("AlbumThread");

    }


    @Override
    public void run() {
        // Query Media Contents from MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
        super.run();
        ContentResolver albumResolver = appContext.getContentResolver();
        Uri mediaContentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        String[] mediaColumns = {
                MediaStore.Audio.Media._ID,
                MediaStore.Audio.Media.ALBUM,
                MediaStore.Audio.Media.ALBUM_ID,
                MediaStore.Audio.Media.DATA,
                MediaStore.Audio.Media.DISPLAY_NAME,


            };

        String mediaSort = "ORDER BY" + MediaStore.Audio.Media.ALBUM_ID + "ASC" + "," + MediaStore.Audio.Media.DISPLAY_NAME + "ASC"; 

        albumCursor = albumResolver.query(mediaContentUri, mediaColumns, null, null, mediaSort);

    }


}

}

【问题讨论】:

  • 请发布您的代码。
  • 对象/类的公共变量可以从所有其他对象访问,无论线程如何。
  • @HowardPautz 以上是我的代码。我也是初学者。

标签: java android multithreading


【解决方案1】:

您无法访问它,因为您在方法中本地声明了它。

将光标声明放在 onCreate() 之外

你可以这么说:

     public Cursor myCursor;

这样你就可以访问它了。

【讨论】:

  • 所以对于我需要更新的每个视图我是否需要在范围内声明它们?如果我声明它也要求我创建为静态变量。没事吧?
  • 在创建线程的时候有没有其他方法可以传入activity的Context,比如MyThread(Myactivity.this)?
  • @RaajForu 想知道您的方法是否会导致您出现问题。为什么需要将上下文传递给线程,从线程回调到线程启动器?此外,使用 Runnable 通常比使用 Thread 更容易。 onCreate 也可能不是启动线程的最佳位置。如果要在另一个线程中访问该游标,您可能会引入难以捕获的数据争用/数据就绪错误,例如当线程要求使用光标时,光标是否仍在获取,等等。
  • 谢谢,我明白了。现在我在另一个线程中设置了查询。我还使用光标从内容 URI 中提取数据。两者都在新线程上。我将所有这些数据放在 2 个列表视图中。我可以使用 Handler 和 Bundle 传递这些列表视图吗?哪个是好方法
  • 如果您想从非主 UI 线程的线程中进行一些更改,您可以使用处理程序。所以声明前:private Handler h=new Handler();并在您的线程中这样称呼它: h.post(new Runnable() { public void run() {...update list views...}});或者您也可以尝试 AsyncTask。但无论如何,如果不使用 Handlers、AsyncTask....,您将无法从自己的线程更改 UI
猜你喜欢
  • 2013-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多