Android服务导致单例的实例变量为null

时间:2015-03-16 11:08:43

标签: android android-service

我有一个名为ClientManager的类,我从服务器加载字典。加载字典后,将启动一个Service(将在其自己的进程中运行),该Service将使用此字典中的数据。但是,当我通过类单例访问字典时,它为null。字典对象驻留在类DataManager中。请参阅以下代码:

ClientManager.java

DataManager mDataManager = DataManager.getInstance();

public void apiCompleted(ApiResult apiResult){
    ....
    DataDictionary dataDict = (DataDictionary) apiResult.valueObject;
    //dictionary loads OK from server since i can see the contents by iterating through it

    mDataManager.addDictionary(dataDict);
    if (!serviceRunning(MyService.class)){
        Intent intent = new Intent(mContext, MyService.class);
        mContext.startService(intent);
    }

MyService.java

public class MyService extends Service {
...
DataManager mDataManager;
@Override
public void onCreate(){
  mDataManager = DataManager.getInstance();

  if(!mDataManager.containsDataDictionary()){
        //toast dictionary is null
  }


}

DataManager.java

public class DataManager {

 private static DataManager instance = null;
 private DataDictionary mDataDictionary = null;

 public static DataManager getInstance(){
    if (instance == null){
        instance = new DataManager();
    }
  return instance;
 }

public boolean containsDataDictionary() {
    if ( m_dataDictionary == null ){
        return false;
    }
    return true;
 }

public DataDictionary getDataDictionary() {
    return mDataDictionary;
}     

public void addDataDictionary(DataDictionary p_dataDictionary) {
    mDataDictionary = p_dataDictionary;
}      
}

3 个答案:

答案 0 :(得分:1)

你自己说:“哪个在自己的过程中运行”

每个进程都有自己的VM。您无法访问从一个进程到另一个进程的变量等。

明确的问题是,您是否绝对需要在自己的流程中运行服务?

答案 1 :(得分:0)

流程之间的数据共享通过IntentsContentProviders完成。

如果数据仅在您的应用程序包中共享,您也可以使用SQLite或SharedPreferences,但这两者都使用非易失性内存,并且明显慢于通过IPC进行数据共享。

答案 2 :(得分:0)

允许Singleton Pattern在应用程序内共享数据,而不是在应用程序之间共享。应用程序的任何实例的生命周期都限制在应用程序生命周期内。看来你正试图在应用程序之外扩展单例对象的范围,这根本不可能......

注意:每个进程都在自己的VM中运行,因此目标进程没有源进程的单例实例。

应用程序有两种通信方式......

1)活动通信(IPC):当源应用程序和目标应用程序都在运行时(即进程),您需要源/发送方应充当服务器,目标/接收方应充当客户端并且两者都应该与Remote Object进行通信,Remote对象具有相同的远程对象签名。Example : AIDL implementation ....

2)被动通信(访问源资源):当Source未处于活动状态且目标正在尝试访问存储在任何类型存储中的源数据时,可以访问通过Intents/Content Provider

如果您想在流程之间共享数据,那么您只需使用AIDL实现...