草庐IT

java - Android 服务创建单例类的新实例

coder 2023-12-12 原文

我正在使用单例类通过应用程序(即一些队列)保存一些数据。

我正在创建我的 Application 类的 Singleton 类实例 onCreate 方法。

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

在此之后,我将在我的 Activity 中的这个单例类中添加数据

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

直到一切正常。我可以在我的 ActivitiesListView 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();

我的单例实例变为空,我的单例创建了新实例。这导致我在服务中丢失了数据。

以下是我的错误流程。

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

以下是我的单例类的代码

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;
    }


}

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);
    }

}

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>

最佳答案

您正在不同的进程中运行您的Service,这与您的Application 上下文不同,这就是队列由null 在新进程中。

从 list 中的 Service 中删除以下内容,您就可以开始了:

android:process=":main"

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

关于java - Android 服务创建单例类的新实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24625638/

有关java - Android 服务创建单例类的新实例的更多相关文章

  1. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

  2. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  5. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  6. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

    我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

  7. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  8. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  9. ruby - 如何使用 RSpec::Core::RakeTask 创建 RSpec Rake 任务? - 2

    如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake

  10. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

随机推荐