在嵌套类中访问全局变量

时间:2014-07-20 04:08:22

标签: java android global-variables

我有一个令人尴尬的问题。对于我的生活,我无法弄清楚为什么我的代码不起作用。

private void getParseObject(String title) {
    final String parseTitle = title;
    ParseQuery<ParseObject> query = ParseQuery.getQuery(title);
    query.findInBackground(new FindCallback<ParseObject>() {
        public void done(List<ParseObject> objects, ParseException e) {
            if (e == null) {
                if (objects.isEmpty()){
                    createParse(parseTitle);
                } else {
                    ParseObject event = objects.get(0);
                    int likes = event.getInt("likes");
                    JSONArray comments = event.getJSONArray("comments");
                    setParseInfo(likes, comments);
                }
             } else {
                Log.v("Miles", String.valueOf(e.getCode()));
             }
        }
    }); 
    Log.v("Miles", "LIKES FROM GOT " + likes);
}

public void setParseInfo(int likesFromParse, JSONArray commentsFromParse) {
    this.likes = likesFromParse;
    this.comments = commentsFromParse;
    Log.v("Miles", "LIKES FROM SET " + likes);
}

在setParseInfo(int,JSONArray)中,我正在设置片段的全局变量。我可以得到信息,它不是空的;在该日志“LIKES FROM SET”中,“likes”int比正常情况更多。但是,当我尝试在“LIKES FROM GOT”日志中的getParseObject()中执行相同操作时,“likes”int显示为0.有关如何解决此问题的任何想法?

编辑1:

根据Ryan J的建议,我尝试过这样的事情,它也有同样的效果。

private void getParseObject(String title) {
    final String parseTitle = title;
    ParseQuery<ParseObject> query = ParseQuery.getQuery(title);
    query.findInBackground(new FindCallback<ParseObject>() {
        int nestedLikes = likes;
        JSONArray nestedComments = comments;

        public void done(List<ParseObject> objects, ParseException e) {
            if (e == null) {
                if (objects.isEmpty()){
                    createParse(parseTitle);
                } else {
                    ParseObject event = objects.get(0);
                    nestedLikes = event.getInt("likes");
                    nestedComments = event.getJSONArray("comments");
                    setParseInfo(nestedLikes, nestedComments);
                }
             } else {
                Log.v("Miles", String.valueOf(e.getCode()));
             }
        }
    }); 
    Log.v("Miles", "LIKES FROM GOT " + likes);
}

我认为这个建议是什么。但是,日志“LIKES FROM GOT”仍然返回0.

1 个答案:

答案 0 :(得分:1)

您需要让主线程等待后台线程完成。

这是使用CountDownLatch使主线程等待的简单方法:

import java.util.concurrent.CountDownLatch;

public class PassOutResult {
    public static void main(String[] args) {
        new PassOutResult().doMainThread();
    }

    void doMainThread() {
        try {
            final CountDownLatch latch = new CountDownLatch(1);
            Thread background = new Thread() {
                public void run() {
                    int r = 2;
                    setResult(r);
                    System.out.println("BackgroundThread: r=" + r);
                    latch.countDown();
                }
            };
            background.start();
            System.out.println("MainThread A: theResult=" + theResult);
            latch.await();
            System.out.println("MainThread B: theResult=" + theResult);
        } catch (InterruptedException ex) {
            System.err.println(ex);
        }
    }
    void setResult(int r) {
        theResult = r;
    }
    int theResult;
}

上述技术适用于Android Java以及Oracle Java(JRE)。

顺便说一句,如果有多个线程正在访问单个变量(例如&#34; theResult&#34;在我的示例代码中),那么您应该同步对它的访问。在我的示例代码中,CoundDownLatch有效地同步访问。但是在一个大型程序中,你无法相信你对线程正在做什么的了解,通常可以更简单地将变量包装在getter / setter方法中,并使这些方法同步。

synchronized int getResult() {
   return theResult;
}
synchronized void setResult(int r) {
   theResult=r;
}

以下是如何在原始代码中使用CountDownLatch:

    private void getParseObject(String title) {
        final String parseTitle = title;
        final CountDownLatch latch = new CountDownLatch(1);
        ParseQuery<ParseObject> query = ParseQuery.getQuery(title);
        query.findInBackground(new FindCallback<ParseObject>() {
            public void done(List<ParseObject> objects, ParseException e) {
                if (e == null) {
                    if (objects.isEmpty()){
                        createParse(parseTitle);
                    } else {
                        ParseObject event = objects.get(0);
                        int likes = event.getInt("likes");
                        JSONArray comments = event.getJSONArray("comments");
                        setParseInfo(likes, comments);
                    }
                 } else {
                    Log.v("Miles", String.valueOf(e.getCode()));
                 }
                latch.countDown();
            }
        }); 
        latch.await();
        Log.v("Miles", "LIKES FROM GOT " + likes);
    }