2012-01-15 36 views
5

Tôi có một lớp hoạt động, trong đó tôi có một lá cờ tĩnh, chúng ta hãy nóiAndroid dễ bay hơi không hoạt động?

public static volatile flag = false; 

Sau đó, trong lớp học, tôi bắt đầu một chủ đề, trong đó kiểm tra các lá cờ và làm những việc khác nhau.

Tôi cũng có bộ phát quảng cáo, đặt cờ thành đúng hoặc sai.

Tôi mặc dù dễ bay hơi sẽ buộc cờ đến giá trị gần đây nhất. Nhưng tôi có thể thấy người phát sóng của tôi đặt cờ tĩnh thành true, nhưng chuỗi của tôi vẫn nhận được nó là sai.

Tôi có thiếu cái gì cơ bản ở đây không? Bất kỳ trợ giúp sẽ được đánh giá cao!

Mã đơn giản (Cập nhật) - Vì vậy, cờ được cho là sẽ thay đổi thành true sau một phút. Nhưng nó không bao giờ làm. Nhưng thông điệp từ máy thu phát sóng cho thấy nó có được thay đổi thành true

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

Nó sẽ hoạt động. Bạn có thể gửi mã của bạn? –

+0

Phiên bản đơn giản trông giống như sau: – Safecoder

+0

Tôi không thấy giá trị của 'cờ' đang được thay đổi. –

Trả lời

7

Tôi nghĩ rằng vấn đề là bạn đang chạy bộ thu theo quy trình riêng của nó. Từ các tài liệu cho android:process thuộc tính của <receiver>:

Nếu tên được gán cho thuộc tính này bắt đầu với một dấu hai chấm (':'), một quá trình mới, tư nhân để ứng dụng, được tạo ra khi nó cần thiết và phát sóng người nhận chạy trong quá trình đó.

Tôi nghĩ rằng người nhận được sửa đổi một phiên bản quá trình địa phương của TestService.flag, không phải là người được sử dụng bởi TestService. Thử xóa thuộc tính android:process khỏi thẻ <receiver> trong tệp kê khai của bạn.

+0

Bạn đã đúng! Sau khi tôi thấy câu hỏi về quy trình dịch vụ của bạn, tôi đã nghĩ về điều tương tự. Tôi chỉ thử nó và nó hoạt động! Cảm ơn nhiều! – Safecoder

0

Từ liên kết này

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

Về cơ bản, dễ bay hơi được sử dụng để chỉ ra rằng giá trị của một biến sẽ được sửa đổi bởi chủ đề khác nhau.

+0

Có, nó được sửa đổi trong Broadcastreceiver mà là khác so với thread chạy trong dịch vụ của tôi – Safecoder

0

Tôi thực sự hy vọng chủ đề dịch vụ của bạn không phải là cái này (tôi không thấy bất kỳ một khác):

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

     } 
    } 

} 

Bởi vì bạn có while(true) ở đây, không while(!flag) như nó phải được.

+1

đây chỉ là một chương trình thử nghiệm tôi đặt cùng một cách nhanh chóng để hiển thị vấn đề. Đó là khi (true) vì tôi muốn hiển thị giá trị cờ để xem nó có bị thay đổi bởi bộ thu phát sóng hay không. nhưng logcat cho thấy nó vẫn là "Cờ là sai" ngay cả sau khi tôi thấy "cờ được thay đổi thành true" từ Broadcastreceiver. – Safecoder

+0

Chạy nó và bạn sẽ thấy những gì tôi có ý nghĩa. Bạn phải đặt bộ lọc cho "cờ được đổi thành true" là thông báo "Flag is false" tiếp tục được in ra trong vòng lặp while. – Safecoder

+0

@Làm thế nào Li: bạn có chắc chắn onReceive nơi bạn đang đặt nó thành false được thực thi không? – Tudor

Các vấn đề liên quan