Java wait()& notify()vs Android wait()&通知()

时间:2014-04-01 11:14:18

标签: java android multithreading wait notify

在弄清楚如何在Java应用程序中使用wait()和notify()从Internet获取一些数据之后,我不得不将该代码迁移到我的Android应用程序中。事实证明,即使试图使其成为多线程(使用Runnable,然后是ASyncTask),在Java应用程序中工作的代码也永远不会在我的Android应用程序中运行。问题似乎是Android应用程序将在Object.wait()上调用后挂起,并且永远不会继续。

以下是Java& amp;的代码。 Android课程:

爪哇

    import java.util.Map;

import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;

public class Getter {
    private String username = "jdk17";
    private String userFullname;
    private Object userObj = new Object();

    public static void main(String[] args) {

        System.out.println("Main");
        String text;
        Getter main = new Getter();
        text = main.getString();
        System.out.println("Main - Text = " + text);
    }

    public String getString() {

        Firebase firebaseRef = new Firebase(
                "https://demoandroid.firebaseio.com/user/username/" + username);

        firebaseRef.addListenerForSingleValueEvent(new ValueEventListener() {

            @Override
            public void onCancelled(FirebaseError arg0) {
            }

            @Override
            public void onDataChange(DataSnapshot snap) {

                System.out.println("***********onDataChange()***********");
                Object obj = snap.getValue();
                userFullname = (String) ((Map) obj).get("fullname");
                System.out.println("********* The text = " + userFullname);
                synchronized (userObj) {
                    userObj.notify();
                }
            }

        });

        try {
            synchronized (userObj) {
                System.out.println("Calling wait()");
                userObj.wait();
            }
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }

        System.out.println("getString() returning text = " + userFullname);
        return userFullname;

    }
}

的Android

package com.example.paabooking;

import java.util.Map;

import android.util.Log;

import com.firebase.client.DataSnapshot;
import com.firebase.client.Firebase;
import com.firebase.client.FirebaseError;
import com.firebase.client.ValueEventListener;


public class FirebaseHelper {
    private final String TAG = "FirebaseHelper";
    private String username = "jdk17";
    private String userFullname;
    private Object userObj = new Object();

    public FirebaseHelper() {}

    public String getString()  {
            Log.d(TAG, "getString()");

        Firebase firebaseRef = new Firebase("https://demoandroid.firebaseio.com/user/username/" + username);

        firebaseRef.addListenerForSingleValueEvent(new ValueEventListener() {

            @Override
            public void onCancelled(FirebaseError arg0) {Log.d(TAG, "cancelled.");}

            @Override
            public void onDataChange(DataSnapshot snap) {

                Log.d(TAG, "***********onDataChange()***********");
                // TODO Auto-generated method stub
                Object obj = snap.getValue();
                userFullname = (String)((Map)obj).get("fullname");
                Log.d(TAG, "********* The text = " + userFullname);
                synchronized(userObj) {
                    userObj.notify();
                }   
            }

        });

        try {
            synchronized (userObj) {
                Log.d(TAG, "Calling wait()");
                userObj.wait();
            }
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }


        Log.d(TAG,"getString() returning text = " + userFullname);
        return userFullname;

    }
}

控制台打印输出:Java

Main
Calling wait()
***********onDataChange()***********
********* The text = Tom Barry
getString() returning text = Tom Barry
Main - Text = Tom Barry

控制台打印输出:Android

getString()
Calling wait()

Java Firebase库 - https://www.firebase.com/docs/java-quickstart.html

1 个答案:

答案 0 :(得分:0)

我不认为这是由于Java和Android中的wait / notify之间存在任何差异(真实或假设)。

我认为您所链接的Firebase页面中的引用解释了这种差异:

  

"默认情况下,在Android上,所有回调都在主线程上执行。在其他JVM目标上,回调在新的单独线程上执行。您可以通过将自己的EventTarget提供给库使用的默认配置来配置此行为。"

在Android案例中,您的主要线程似乎是实例化Firebase对象,添加侦听器,然后调用wait()。但是wait()阻塞了主线程...所以,当然主线程无法接受将其唤醒的回调。因此,一切都冻结了。

引言的第二句似乎暗示了解决问题的方法。


我之前从未遇到Firebase,更不用说尝试使用它了。这只是基于我对文档和代码的肤浅阅读。