Android服务创建Singleton类的新实例

Ahm*_*waz 5 java singleton android android-service

我正在使用A Singleton Class来保存一些数据,这些数据来自应用程序,这是一些Queue.

我正在创建onCreate我的ApplicationClass的Singleton类实例方法.

 @Override
 public void onCreate() {
    super.onCreate();
    mInstance = this;
    mContext = getApplicationContext();
    Queue.getInstance(); // this is my singleton class instance
  }
Run Code Online (Sandbox Code Playgroud)

在此之后,我将在我的活动中添加此单例类中的数据

Queue.getInstance().addItem(qItem);
Log.d(Constants.TAG, "Added Item Queue Size: "+Queue.getInstance().getQueueList().size());
Run Code Online (Sandbox Code Playgroud)

直到这一切工作正常.我可以在我的访问数据Activities,并ListView Adapter然而,当我启动服务,并尝试访问数据onCreate服务

Log.d(Constants.TAG, "Playing Item Queue Size: "+Queue.getInstance().getQueueList().size()+" Current Item No. "+Queue.getInstance().getCurrentPlayingItem());
String url = Queue.getInstance().getQueueItem(Queue.getInstance().getCurrentPlayingItem()).getLinkUrl();
Run Code Online (Sandbox Code Playgroud)

我的Singleton实例变为null,我的单例创建新实例.这导致我的服务内部数据丢失.

以下是我的错误流程.

  1. 在应用程序启动时创建实例 - 工作
  2. 从活动和适配器添加数据 - 工作
  3. 启动服务和访问数据 - 不工作,因为单例实例在服务中变为空

以下是我的Singleton类的代码

import java.util.ArrayList;

import com.taazi.utils.Constants;

import android.util.Log;

public class Queue {
    private ArrayList<QueueItem> mQueueList;
    static Queue mInstance;
    private int currentPlayingItem=0;

    private Queue(){
        mQueueList = new ArrayList<QueueItem>();
    }

    public static Queue getInstance(){
        if(mInstance == null){
            mInstance = new Queue();
            Log.d(Constants.TAG, "New Instance");
        }
        return mInstance;
    }

    public void addItem(QueueItem item){
        mQueueList.add(item);
    }

    public void removeItem(int position){
        mQueueList.remove(position);
    }

    public ArrayList<QueueItem> getQueueList(){
        return mQueueList;
    }

    public QueueItem getQueueItem(int position){
        return mQueueList.get(position);
    }

    public int getCurrentPlayingItem() {
        return currentPlayingItem;
    }

    public void setCurrentPlayingItem(int currentPlayingItem) {
        this.currentPlayingItem = currentPlayingItem;
    }


}
Run Code Online (Sandbox Code Playgroud)

AudioPlayBackService.Java

package com.taazi.services;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.IBinder;
import android.util.Log;

import com.taazi.helper.NotificationHelperNew;
import com.taazi.models.Queue;
import com.taazi.models.QueueItem;
import com.taazi.utils.Constants;

public class AudioPlayBackService extends Service {

    /**
     * Called to go toggle between pausing and playing the music
     */
    public static final String TOGGLEPAUSE_ACTION = "com.taazi.services.togglepause";

    /**
     * Called to go to pause the playback
     */
    public static final String PAUSE_ACTION = "com.taazi.services.pause";

    /**
     * Called to go to stop the playback
     */
    public static final String STOP_ACTION = "com.taazi.services.stop";

    /**
     * Called to go to the previous track
     */
    public static final String PREVIOUS_ACTION = "com.taazi.services.previous";

    /**
     * Called to go to the next track
     */
    public static final String NEXT_ACTION = "com.taazi.services.next";

    /**
     * Used to build the notification
     */
    private NotificationHelperNew mNotificationHelper;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    MediaPlayer player;

    @Override
    public void onCreate() {
        super.onCreate();
     // Initialize the notification helper
        mNotificationHelper = new NotificationHelperNew(this);

        Log.d(Constants.TAG, "Playing Item Queue Size: "+Queue.getInstance().getQueueList().size()+" Current Item No. "+Queue.getInstance().getCurrentPlayingItem());
        String url = Queue.getInstance().getQueueItem(Queue.getInstance().getCurrentPlayingItem()).getLinkUrl();
        player = MediaPlayer.create(this, Uri.parse(url));
        player.setLooping(false); // Set looping
        updateNotification();
    }
    public int onStartCommand(Intent intent, int flags, int startId) {
        player.start();
        return 1;
    }

    public void onStart(Intent intent, int startId) {
        // TO DO
    }
    public IBinder onUnBind(Intent arg0) {
        // TO DO Auto-generated method
        return null;
    }

    public void onStop() {

    }
    public void onPause() {

    }
    @Override
    public void onDestroy() {
        mNotificationHelper.killNotification();
        player.stop();
        player.release();
    }

    @Override
    public void onLowMemory() {

    }

    /**
     * Updates the notification, considering the current play and activity state
     */
    private void updateNotification() {
        QueueItem item =  Queue.getInstance().getQueueItem(Queue.getInstance().getCurrentPlayingItem());
            mNotificationHelper.buildNotification("", item.getArtist(),
                    item.getTitle(), (long)50, null, true);
    }

}
Run Code Online (Sandbox Code Playgroud)

AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.taazi.android"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="10"
        android:targetSdkVersion="20" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.GET_TASKS" />


    <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />

    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <application
        android:name="com.taazi.app.AppController"
        android:allowBackup="true"
        android:hardwareAccelerated="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.Apptheme" >
        <activity
            android:name="com.taazi.activities.MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Music service -->
        <service
            android:name="com.taazi.services.AudioPlayBackService"
            android:label="@string/app_name"
            android:process=":main" />

    </application>

</manifest>
Run Code Online (Sandbox Code Playgroud)

waq*_*lam 5

您正在运行Service与您的Application上下文不同的不同进程,这就是为什么Queue 在新进程中的结果为null.

从你Service的清单中删除以下内容,你很高兴:

android:process=":main"
Run Code Online (Sandbox Code Playgroud)

此外,我建议你HandlerThread在服务中使用卸载一些繁重的操作.