2012-01-15 11 views
5

मैं एक गतिविधि वर्ग, जिसमें मैं एक स्थिर ध्वज होता है, मान लें किएंड्रॉइड अस्थिर काम नहीं कर रहा है?

public static volatile flag = false; 

फिर कक्षा में, मैं एक धागा है, जो ध्वज की जाँच करता है शुरू करने और अलग अलग बातें करते हैं।

मेरे पास एक प्रसारणकर्ता भी है, जो ध्वज को सही या गलत पर सेट करता है।

हालांकि मैं अस्थिर फ्लैग को सबसे हाल के मूल्य पर मजबूर कर दूंगा। लेकिन मैं देख सकता हूं कि मेरा ब्रॉडकास्टसीवर स्थिर ध्वज को सत्य पर सेट करता है, लेकिन मेरा धागा अभी भी इसे झूठा मान रहा है।

क्या मुझे यहां कुछ बुनियादी याद आ रही है? किसी भी सहायता की सराहना की जाएगी!

सरलीकृत कोड (अपडेटेड) - तो ध्वज एक मिनट के बाद सच में बदलना चाहिए। लेकिन यह कभी नहीं किया। लेकिन प्रसारण रिसीवर से संदेश से पता चलता है कि यह सच

TestappActivity.java के लिए किया गया बदल गया है:

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:

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 विशेषता के लिए डॉक्स से:

नाम इस विशेषता को आवंटित किए गए (':') पेट के साथ शुरू होता है, तो एक नई प्रक्रिया, आवेदन करने के लिए निजी, जब यह आवश्यक है बनाई गई है और प्रसारण रिसीवर उस प्रक्रिया में चलाता है।

मुझे लगता है कि रिसीवर TestService.flag की एक प्रक्रिया-स्थानीय संस्करण को संशोधित किया जाता है, नहीं एक TestService द्वारा इस्तेमाल किया जा रहा है। अपने मेनिफेस्ट में <receiver> टैग से android:process विशेषता को निकालने का प्रयास करें।

+0

आप सही हैं! आपके सेवा प्रक्रिया के प्रश्न के बाद, मैं इसके बारे में सोच रहा था। मैंने अभी कोशिश की और यह काम करता है! बहुत धन्यवाद! – Safecoder

0

इस लिंक

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

अनिवार्य रूप से, अस्थिर संकेत मिलता है कि एक वेरिएबल का मान अलग धागे द्वारा संशोधित किया जा जाएगा प्रयोग किया जाता है।

+0

हां, यह ब्रॉडकास्ट्रेसीवर में संशोधित है जो मेरी सेवा – Safecoder

0

मैं सच में आशा है कि आपकी सेवा धागा इस एक नहीं है (मैं किसी भी अन्य एक देख पा रहे हैं नहीं):

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(true) यहाँ है, नहीं while(!flag) के रूप में यह होना चाहिए।

+1

में चल रहे थ्रेड से भिन्न है, यह केवल एक परीक्षण प्रोग्राम है जिसे मैंने समस्या को दिखाने के लिए जल्दी से रखा है। यह जबकि (सच) है क्योंकि मैं फ्लैग वैल्यू प्रदर्शित करना चाहता हूं यह देखने के लिए कि क्या यह प्रसारण रिसीवर द्वारा बदला गया है। लेकिन लॉककैट दिखाता है कि ब्रॉडकास्टसेवर से "झंडा बदल गया है" देखने के बाद भी "झंडा झूठा है"। – Safecoder

+0

इसे चलाएं और आप देखेंगे कि मेरा क्या मतलब है। आपको "ध्वज गलत है" के लिए एक फ़िल्टर सेट करना होगा क्योंकि संदेश "झंडा झूठा है" जारी रहता है जबकि लूप में मुद्रित हो जाता है। – Safecoder

+0

@ हावर्ड ली: क्या आप निश्चित हैं कि ऑन-रिसीव जहां आप इसे गलत पर सेट कर रहे हैं निष्पादित किया गया है? – Tudor