无法从广播接收器启动的asynctask中访问共享首选项

时间:2015-11-20 06:11:42

标签: android android-asynctask broadcastreceiver

我有一个从广播接收器开始的asynctask。

代码:

public static class SrvPositioning extends Service {

        // An alarm for rising in special times to fire the
        // pendingIntentPositioning
        private AlarmManager alarmManagerPositioning;
        // A PendingIntent for calling a receiver in special times
        public PendingIntent pendingIntentPositioning;

        Location location;
        //GPSTracker gps;



        @Override
        public void onCreate() {
            super.onCreate();
            alarmManagerPositioning = (AlarmManager) 
                    getSystemService(Context.ALARM_SERVICE);
            Intent intentToFire = new Intent(
                    ReceiverPositioningAlarm.ACTION_REFRESH_SCHEDULE_ALARM);
            intentToFire.putExtra(ReceiverPositioningAlarm.COMMAND,
                    ReceiverPositioningAlarm.SENDER_SRV_POSITIONING);
            pendingIntentPositioning = PendingIntent.getBroadcast(this, 0,
                    intentToFire, 0);



        };

        @Override
        public void onStart(Intent intent, int startId) {
            try {
                long interval = 3000;//3 secs
                System.out.println("Service called");
                int alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;
                long timetoRefresh = SystemClock.elapsedRealtime();
                alarmManagerPositioning.setInexactRepeating(alarmType,
                        timetoRefresh, interval, pendingIntentPositioning);

                //Toast.makeText(this, "SrvPositioning fired", Toast.LENGTH_SHORT).show();

            } catch (NumberFormatException e) {
                Toast.makeText(this,
                        "error running service: " + e.getMessage(),
                        Toast.LENGTH_SHORT).show();
            } catch (Exception e) {
                Toast.makeText(this,
                        "error running service: " + e.getMessage(),
                        Toast.LENGTH_SHORT).show();
            }
        }



        @Override
        public void onDestroy() {
            this.alarmManagerPositioning.cancel(pendingIntentPositioning);
            // ReceiverPositioningAlarm.stopLocationListener();
        }

        @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            return null;
        }


    }


    public static class ReceiverPositioningAlarm extends BroadcastReceiver {

        public static final String COMMAND = "SENDER";
        public static final int SENDER_ACT_DOCUMENT = 0;
        public static final int SENDER_SRV_POSITIONING = 1;

        public static final String ACTION_REFRESH_SCHEDULE_ALARM =
                "ACTION_REFRESH_SCHEDULE_ALARM";
        //private static final Context _context=null;
        String jsonStr="";


        @Override
        public void onReceive(final Context context, Intent intent) {
            //Toast.makeText(context, "new request received by receiver",
            //Toast.LENGTH_SHORT).show();

            // create class object

            //SessionManager s=new SessionManager(context);
            //userid=s.getUserId();
            System.out.println("RecieverPositioning Alarm");
            //_context = context;


            new ChatScreen().new GetPeriodicChat(recieverid).execute();
        }
    }

服务和广播接收器都是ChatScreen类的内部类。

我在ChatScreen.java的onCreate()中初始化了一个共享首选项,如:

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.chatscreen2);
    preftimestamp= ChatScreen.this.getSharedPreferences(Constants.ACCESS_TIMESTAMP, Context.MODE_PRIVATE);

现在,当我尝试在asynctask GetPeriodicChat(recieverid)(从广播接收器启动的那个)的doInBackground()中访问此共享首选项时,我遇到了NPE。

以下是asynctask的代码:

public class GetPeriodicChat extends AsyncTask<String,String,String>{
    String r_id="";

    public GetPeriodicChat(String r_id) {
        // TODO Auto-generated constructor stub
        System.out.println("get periodic chat called");
        chatlisthashmapperiodically = new ArrayList<HashMap<String, String>>();
        preftimestamp= ChatScreen.this.getSharedPreferences(Constants.ACCESS_TIMESTAMP, Context.MODE_PRIVATE);
        this.r_id=r_id;
    }
    protected void onPreExecute() {
        super.onPreExecute();
        try{
            //showLoading(R.string.loading);
        }catch(Exception e){
            e.printStackTrace();
        }

    }
    @Override
    protected String doInBackground(String... params) {
        // TODO Auto-generated method stub

        urlgetallchatmessage=Constants.getmessagetimestamp;
        nameValuePairs = new ArrayList<NameValuePair>(2);
        nameValuePairs.add(new BasicNameValuePair("sender_id",userid));
        nameValuePairs.add(new BasicNameValuePair("receiver_id",r_id));//rec

        String last_timestamp =preftimestamp.getString(Constants.ACCESS_TIMESTAMP,null);
        System.out.println("Last timestamp in periodically-->"+last_timestamp);
        nameValuePairs.add(new BasicNameValuePair("last_timestamp",last_timestamp));


        ServiceHandle sh = new ServiceHandle();
        String jsonResponse  = sh.makeServiceCall(urlgetallchatmessage, ServiceHandle.POST,nameValuePairs);

        // after getting  JSON string from the URL
        System.out.println(""+ jsonResponse );
        try {

            if ( jsonResponse  != null) 
            {
                JSONObject c = new JSONObject( jsonResponse );

                //JSONObject c = jsonObj;
                successallchat=Integer.parseInt(c.getString("success"));
                if(successallchat==1)
                {

                    if(c.has(TAG_GETHISTORY_ARRAY)){
                        chatlistperiodically = c.getJSONArray(TAG_GETHISTORY_ARRAY);

                        // looping through All Contacts
                        for (int i = 0; i <chatlistperiodically.length(); i++) {
                            JSONObject j_chat = chatlistperiodically.getJSONObject(i);
                            String timestamp= j_chat.getString(TAG_TIMESTAMP);
                            String chatmessage= j_chat.getString(TAG_MESSAGE);
                            String sender_id= j_chat.getString(TAG_SENDER_ID);

                            // creating new HashMap
                            HashMap<String, String> map = new HashMap<String, String>();

                            // adding each child node to HashMap key => value
                            map.put(TAG_TIMESTAMP,timestamp);
                            map.put(TAG_MESSAGE,chatmessage);
                            map.put(TAG_SENDER_ID,sender_id);
                            SharedPreferences.Editor editor = preftimestamp.edit();
                            //  System.out.println(projectid+"--->In Projectactivity");
                            editor.putString(Constants.ACCESS_TIMESTAMP,timestamp);
                            editor.commit();


                            //map.put(TAG_PDESC,pdetails);
                            chatlisthashmapperiodically.add(map);
                        }
                    }   
                }
            }
            else
            {
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        Toast.makeText(getBaseContext(), "Server not responding!", Toast.LENGTH_SHORT).show();
                    }
                });

            }
        } catch (Exception e) 
        {
            e.printStackTrace();
        }


        return null;
    }//doInbacckground


    @SuppressLint("NewApi")
    protected void onPostExecute(String file_url) { 


        //removeLoading();

        if(successallchat==1)
        {


        }

    }//postexecute

    }//Asynctask

我在asynctask的构造函数中遇到行preftimestamp= ChatScreen.this.getSharedPreferences(Constants.ACCESS_TIMESTAMP, Context.MODE_PRIVATE);上的NPE。可能是什么问题?如果我没有在构造函数上定义asynctask,那么我也遇到了NPE.Please帮助。< / p>

2 个答案:

答案 0 :(得分:1)

将AsyncTask更新为:

public class GetPeriodicChat extends AsyncTask<String,String,String>{
    String r_id="";

    public GetPeriodicChat(String r_id, Context context) {
        ...
        // ************ Instead of ChatScreen.this pass Context object in constuctor and use it here.
        preftimestamp= context.getSharedPreferences(Constants.ACCESS_TIMESTAMP, Context.MODE_PRIVATE); 
        ...
    } 
}//Asynctask 

用法:

new ChatScreen().new GetPeriodicChat(recieverid, context).execute();

将活动上下文作为参数传递给AsyncTask。除非您在活动中定义静态Context变量,否则您将无法访问活动之外的Activity上下文,这不是最佳做法。

答案 1 :(得分:0)

您不应在广播接收器中执行任何长时间操作,最好从接收器调用服务并在句柄意图上定义异步任务。 如果它在主线程上运行,你永远不应该在其中执行长时间运行的操作(在考虑阻塞接收器和被杀死的候选者之前,系统允许超时10秒。)