服务之前Android的活动访问服务的静态引用已准备就绪 [英] Android activity accessing service's static reference before the service is ready

查看:151
本文介绍了服务之前Android的活动访问服务的静态引用已准备就绪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想火从活动一文本到语音服务,并基于某些事件的活动会引起相应的字符串被发送到讲出来的服务。

下面是我的TTSService:

 公共类TTSService扩展服务实现TextToSpeech.OnInitListener {    私人字符串str;
    私人文字转语音MTTS;
    私有静态最后弦乐TAG =TTSService;
    公共静态TTSService sInstance;    @覆盖    公众的IBinder onBind(意向为arg0){        返回null;
    }
    @覆盖
    公共无效的onCreate(){        MTTS =新的文字转语音(这一点,
                这// OnInitListener
        );
        mTts.setSpeechRate(0.5F);
        Log.v(TAGoncreate_service);
        海峡=左转请;
        super.onCreate();
        sInstance =这一点;
    }
    @覆盖
    公共无效的onDestroy(){
        // TODO自动生成方法存根
        如果(MTTS!= NULL){
            mTts.stop();
            mTts.shutdown();
        }
        super.onDestroy();
    }
    @覆盖
    公共无效的OnInit(INT状态){
        Log.v(TAG的OnInit);
        如果(状态== TextToSpeech.SUCCESS){
            INT结果= mTts.setLanguage(Locale.US);
            如果(结果== || TextToSpeech.LANG_MISSING_DATA
                    结果== TextToSpeech.LANG_NOT_SUPPORTED){
                Log.v(TAG,语言是不可用的。);
            }其他{                的sayHello(STR);            }
        }其他{
            Log.v(TAG,无法初始化文字转语音);
        }
    }
    公共无效的sayHello(字符串str){
        mTts.speak(STR,
                TextToSpeech.QUEUE_FLUSH,
                空值);
    }
}

下面是我的活动的code创建服务:

 公共无效的onCreate(捆绑savedInstanceState){
         // code的休息.....
        意图serviceIntent =新的Intent();
        serviceIntent.setAction(com.packagename.texttospeech.TTSService);
        startService(serviceIntent);
}

下面是活动的onSensorChanged事件处理程序:

  @覆盖
    公共无效onSensorChanged(SensorEvent事件){
        浮距离= event.values​​ [0];
        而(TTSService.sInstance == NULL){
            尝试{
                视频下载(100);
            }赶上(InterruptedException的E){
                e.printStackTrace(); //改变catch语句使用文件的身体|设置|文件模板。
            }
        }
        TTSService.sInstance.sayHello(Float.valueOf(距离)的ToString());    }

现在,当我运行上面的活动,它挂起并没有响应。

在上面移除while循环,我碰到下面的错误跟踪:

  ERROR / AndroidRuntime(7469):致命异常:主要
        显示java.lang.NullPointerException
        在com.packagename.texttospeech.SensorTestActivity.onSensorChanged(SensorTestActivity.java:51)
        在android.hardware.SensorManager $ ListenerDelegate $ 1.handleMessage(SensorManager.java:456)
        在android.os.Handler.dispatchMessage(Handler.java:99)
        在android.os.Looper.loop(Looper.java:123)
        在android.app.ActivityThread.main(ActivityThread.java:4633)
        在java.lang.reflect.Method.invokeNative(本机方法)
        在java.lang.reflect.Method.invoke(Method.java:521)
        在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:858)
        在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
        在dalvik.system.NativeStart.main(本机方法)

所以很明显的问题是,在该行( SensorTestActivity.java:51

  TTSService.sInstance.sayHello(Float.valueOf(距离)的ToString());

下面的 sInstance 为null这表明TTSService的的onCreate()尚待finished.So应该如何我让我的活动等待,直到 TTSService 是随时可以使用?


解决方案

  

所以,我应该怎么做我的活动等待,直到TTSService是随时可以使用?


您没有。最有可能的,就摆脱了服务的完全的,因为它似乎没有必要。有活动中使用文字转语音直接

如果您有明显原因,您的应用需要这是一个服务:

第1步:删除公共静态TTSService sInstance 的sayHello()

第二步:摆脱现有的 startService()通话

第三步:替换 TTSService.sInstance.sayHello(Float.valueOf(距离)的ToString()); startService() 呼叫,发送命令到服务,在这里可以说该消息被添加为字符串额外的费用。

步骤4:在 onStartCommand()为您服务,如果TTS初始化完成后,调用说话()来申请的字符串(从额外的拉动)说。如果TTS初始化还没有完成,追加字符串到的ArrayList<弦乐方式>

第五步:在的OnInit(),更换你的 NullPointerException异常 - 产生的sayHello字符串>()用遍历所有的的ArrayList&LT叫内容说话()他们每个人。

这样,你的活动不关心TTS引擎是否准备好了没有。它简单地将请求发送到该服务,哪些队列它,直到TTS准备,此时它将被播放。

I am trying to fire a Text to speech service from an activity and the activity based on certain events would cause the appropriate string to be sent to the service which speaks out.

Here is my TTSService:

public class TTSService extends Service implements TextToSpeech.OnInitListener{

    private String str;
    private TextToSpeech mTts;
    private static final String TAG="TTSService";
    public static TTSService sInstance;



    @Override

    public IBinder onBind(Intent arg0) {

        return null;
    }


    @Override
    public void onCreate() {

        mTts = new TextToSpeech(this,
                this  // OnInitListener
        );
        mTts.setSpeechRate(0.5f);
        Log.v(TAG, "oncreate_service");
        str ="turn left please ";
        super.onCreate();
        sInstance=this;
    }


    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        if (mTts != null) {
            mTts.stop();
            mTts.shutdown();
        }
        super.onDestroy();
    }


    @Override
    public void onInit(int status) {
        Log.v(TAG, "oninit");
        if (status == TextToSpeech.SUCCESS) {
            int result = mTts.setLanguage(Locale.US);
            if (result == TextToSpeech.LANG_MISSING_DATA ||
                    result == TextToSpeech.LANG_NOT_SUPPORTED) {
                Log.v(TAG, "Language is not available.");
            } else {

                sayHello(str);

            }
        } else {
            Log.v(TAG, "Could not initialize TextToSpeech.");
        }
    }
    public void sayHello(String str) {
        mTts.speak(str,
                TextToSpeech.QUEUE_FLUSH,
                null);
    }
}

Here is my activity's code to create the service:

public void onCreate(Bundle savedInstanceState) {
         //rest of code.....
        Intent serviceIntent = new Intent();
        serviceIntent.setAction("com.packagename.texttospeech.TTSService");
        startService(serviceIntent);
}

Here is the activity's onSensorChanged event handler:

 @Override
    public void onSensorChanged(SensorEvent event) {
        float distance = event.values[0];
        while(TTSService.sInstance==null){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
        TTSService.sInstance.sayHello(Float.valueOf(distance).toString());

    }

Now when I run the activity above, it hangs and does not respond.

On removing the while loop above, I get the following error trace:

ERROR/AndroidRuntime(7469): FATAL EXCEPTION: main
        java.lang.NullPointerException
        at com.packagename.texttospeech.SensorTestActivity.onSensorChanged(SensorTestActivity.java:51)
        at android.hardware.SensorManager$ListenerDelegate$1.handleMessage(SensorManager.java:456)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:123)
        at android.app.ActivityThread.main(ActivityThread.java:4633)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:521)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
        at dalvik.system.NativeStart.main(Native Method)

So clearly the problem is that in the line(SensorTestActivity.java:51):

TTSService.sInstance.sayHello(Float.valueOf(distance).toString());

Here the sInstance is null which suggests that TTSService's onCreate() is yet to be finished.So how should I make my activity wait till the TTSService is ready to be used?

解决方案

So how should I make my activity wait till the TTSService is ready to be used?

You don't. Most likely, you get rid of the service entirely, as it does not appear to be necessary. Have the activity use TextToSpeech directly.

If you have a demonstrable reason why your app needs this to be in a service:

Step #1: Delete public static TTSService sInstance and the sayHello() method.

Step #2: Get rid of your existing startService() call.

Step #3: Replace TTSService.sInstance.sayHello(Float.valueOf(distance).toString()); with a startService() call, to send a command to the service, where the message to be said is added as a String extra.

Step #4: In onStartCommand() of your service, if the TTS initialization is complete, call speak() to speak the requested string (pulled from the extra). If the TTS initialization is not yet complete, append the string to an ArrayList<String>.

Step #5: In onInit(), replace your NullPointerException-generating sayHello() call with a loop over the ArrayList<String> contents to speak() each of them.

This way, your activity does not care whether the TTS engine is ready or not. It simply sends the request to the service, which queues it up until TTS is ready, at which time it will be played.

这篇关于服务之前Android的活动访问服务的静态引用已准备就绪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆