2012-01-15 10 views
5

私は、Activityクラスを持っている私は、静的な旗を持っている、のはAndroidの揮発性が機能していませんか?

public static volatile flag = false; 

はその後、クラスで、私はフラグをチェックスレッドを起動して、別のことを行うとしましょう。

私はまた、フラグをtrueまたはfalseに設定するbroadcastreceiverも持っています。

私はvolatileですが、フラグを最新の値に強制します。しかし、私は私の放送受信機がtrueに静的フラグを設定することがわかりますが、私のスレッドはまだ偽としてそれを取得しています。

ここで基本的なものはありませんか?どんな助けもありがとう!

簡略化されたコード(更新済み) - フラグは1分後にtrueに変更されるはずです。しかしそれは決してしなかった。

package com.test; 

import java.util.Calendar; 

import android.app.Activity; 
import android.app.AlarmManager; 
import android.app.PendingIntent; 
import android.content.Intent; 
import android.os.Bundle; 

public class TestappActivity extends Activity { 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     Intent intent0 = new Intent(this, TestService.class); 
     this.startService(intent0); 

     Intent intent = new Intent(this, TestReceiver.class); 
     AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); 
     PendingIntent sender = PendingIntent.getBroadcast(this, 
       1, intent, 
       PendingIntent.FLAG_UPDATE_CURRENT); 
     Calendar slot = Calendar.getInstance(); 
     int min = slot.get(Calendar.MINUTE); 
     slot.set(Calendar.MINUTE, min+1); 
     am.set(AlarmManager.RTC_WAKEUP, slot.getTimeInMillis(), sender); 
    } 
} 

TestService.java:

package com.test; 

import android.app.Service; 
import android.content.Intent; 
import android.os.IBinder; 
import android.util.Log; 

public class TestService extends Service { 

    private static final String TAG = "TestService"; 

    public static volatile boolean flag = false; 

    private MyTopThread mTopThread; 

    public TestService() { 
    } 

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


    @Override 
    public void onCreate() { 

    } 

    @Override 
    public void onDestroy() { 

    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     protect(); 

     // We want this service to continue running until it is explicitly 
     // stopped, so return sticky. 
     return START_STICKY; 
    } 


    /** 
    * Run protection 
    * 
    */ 
    private void protect() { 

     mTopThread = new MyTopThread(); 
     mTopThread.start(); 
    } 


    private class MyTopThread extends Thread { 

     @Override 
     public void run() { 
      while (true) { 
       try { 
        Thread.sleep(150); 
        Log.d(TAG, "Flag is " + TestService.flag); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 

      } 
     } 

    } 
} 

TestReceiver.java:

しかし、放送受信機からのメッセージは、それが真の

TestappActivity.javaに変更されている示してい

package com.test; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class TestReceiver extends BroadcastReceiver { final static private String TAG = "TestReceiver"; @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "onReceive is triggered ..."); TestService.flag = true; Log.d(TAG, "flag is changed to " + TestService.flag); } } 

のAndroidManifest.xml:基本的には、このリンクから

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

    <uses-sdk android:minSdkVersion="8" /> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 
     <activity 
      android:name=".TestappActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

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

     <service android:name=".TestService" /> 

     <receiver 
      android:name=".TestReceiver" 
      android:process=":remote" > 
     </receiver> 
    </application> 

</manifest> 
+0

これは機能するはずです。コードを投稿できますか? –

+0

簡略化されたバージョンは次のようになります: – Safecoder

+0

'flag 'の値がどこで変更されているのかわかりません。 –

答えて

7

問題は、受信者が独自のプロセスで実行していることです。 <receiver>android:process属性のドキュメントから:

この属性に割り当てられた名前は、コロン(「:」)で始まる場合、それが必要だときに作成され、アプリケーションにプライベート新しいプロセス、および放送受信機はそのプロセスで動作します。

Iは、受信機がTestService.flagのプロセスローカルバージョンではなく、TestServiceによって使用されているものを変更していると思います。マニフェストの<receiver>タグからandroid:process属性を削除してみてください。

+0

あなたは正しいです!あなたの奉仕プロセスの問題を見た後、私は同じことを考えていました。私はちょうどそれを試して、それは動作します!どうもありがとう! – Safecoder

0

http://www.javamex.com/tutorials/synchronization_volatile.shtml

は、揮発性は、変数の値が別のスレッドによって変更される れることを示すために使用されます。それがあるべきとしてあなたがここにwhile(true)を持っているので、

private class MyTopThread extends Thread { 

    @Override 
    public void run() { 
     while (true) { 
      try { 
       Thread.sleep(150); 
       Log.d(TAG, "Flag is " + TestService.flag); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 

     } 
    } 

} 

ないwhile(!flag)

+0

はい、私のサービスで実行されているスレッドとは異なるBroadcastreceiverで修正されました – Safecoder

0

は、私は本当に(私は他のものを見ない)あなたのサービスのスレッドがこのものではありません願っています。

+1

これは問題を示すためにすぐにまとめたテストプログラムです。それは放送受信機によって変更されているかどうかを見るためにフラグ値を表示したいので、while(true)です。しかし、logcatは、 "flag is true"に変更されても、 "Flag is false"のままであることを示しています。 – Safecoder

+0

これを実行すると、私の言いたいことが分かります。 "Flag is false"というメッセージがwhileループで出力され続けると、 "flag is trueに変更されました"というフィルタを設定する必要があります。 – Safecoder

+0

@Howard Li:あなたがfalseに設定しているonReceiveが実行されていることは確かですか? – Tudor

関連する問題