从asynctask传递上下文?

时间:2014-01-07 15:02:53

标签: android android-asynctask

好的,我有一个运行asynctask的任务服务类,然后在满足条件时启动通知。在发送方法中有一个空指针异常,其中创建了Intent,上下文具有所有空值。我不认为我正确地从BloodLevelParse asynctask传递上下文?不确定我还能尝试什么。这是班级:

public class TaskService extends IntentService {

    private ArrayList<BloodLevels> BloodLevelList;

    private String bloodLevel;
    private String bloodType;
    private Integer bloodLevelDays;

    private MyProfileActivity myProfileActivity;

    private BloodLevelParse bloodLevelParse;

    public TaskService() {
        super("TaskService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        // Pass through the blood type
        Bundle bundle = intent.getExtras();
        bloodType = bundle.getString("currentBloodType2");

        // Only perform check if there is an internet connection
        if (CheckNetwork.isInternetAvailable(TaskService.this)) {

            // Check the current blood level for the given blood type
            new BloodLevelParse(this).execute(bloodType);

        } else {
            Toast.makeText(
                    TaskService.this,
                    "Unable to perform daily blood level check, no internet connection.",
                    Toast.LENGTH_LONG).show();
        }

    }

    private void sendNotification(Context context) {

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
                this).setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle("Blood Level Notification")
                .setContentText(bloodLevel);

        Intent resultIntent = new Intent(this, MyProfileActivity.class);

        // Because clicking the notification opens a new ("special") activity,
        // there's no need to create an artificial back stack.
        PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0,
                resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        mBuilder.setContentIntent(resultPendingIntent);

        // Sets an ID for the notification
        int mNotificationId = 001;
        // Gets an instance of the NotificationManager service
        NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        // Builds the notification and issues it.
        mNotifyMgr.notify(mNotificationId, mBuilder.build());

    }

    public class BloodLevelParse extends
            AsyncTask<String, Void, ArrayList<BloodLevels>> {

        private Context myCtx;

        public BloodLevelParse(Context ctx){
            // Now set context
            this.myCtx = ctx;
        }

        protected ArrayList<BloodLevels> doInBackground(String... params) {

            String bloodType = params[0];

            try {

                // HTTP PROTOCOL
                Document doc = Jsoup
                        .connect(
                                "http://www.giveblood.ie/Current_Blood_Supply/")
                        .timeout(5000)
                        .userAgent(
                                "Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
                        .cookie("auth", "token").get();

                // EXTRACT SPECIFIC ELEMENTS FROM THE HTML
                Elements bloodsupplylines1 = doc.select("td.bloodsupplyline");
                Elements bloodsupplylines2 = bloodsupplylines1
                        .select("img[src~=(?i)\\.(png|jpe?g|gif)]");

                // CREATE LIST AND POPULATE IT WITH ELEMENTS RETRIEVE FROM HTML
                List<String> BloodLevelRawList = new ArrayList<String>();

                for (Element bloodsupplyline : bloodsupplylines2) {

                    BloodLevelRawList.add(new String(bloodsupplyline
                            .attr("alt")));

                }

                BloodLevelList = new ArrayList<BloodLevels>();

                for (int i = 0; i < BloodLevelRawList.size(); i += 2) {
                    // Only add to BloodLevelList if it is the blood type
                    // selected
                    if (BloodLevelRawList.get(i).equals(bloodType)) {

                        BloodLevelList.add(new BloodLevels(BloodLevelRawList
                                .get(i), BloodLevelRawList.get(i + 1)));
                    }
                }

            }

            catch (IOException ioex) {
                ioex.printStackTrace();
            }

            return BloodLevelList;

        }

        @Override
        protected void onPostExecute(ArrayList<BloodLevels> BloodLevelList) {

            String bloodLevelReplace = BloodLevelList.get(0).getBloodLevel()
                    .replaceAll("Blood supply", "");

            bloodLevel = ("Current blood levels for "
                    + BloodLevelList.get(0).getBloodType() + " is" + bloodLevelReplace);

            // Get the number of days from the blood level string
            Scanner in = new Scanner(bloodLevel).useDelimiter("[^0-9]+");
            int bloodLevelDays = in.nextInt();

            // Send notification if no. of days blood level supply goes below 5
            if (bloodLevelDays < 5) {

                TaskService taskService = new TaskService();
                taskService.sendNotification(myCtx);
            }

        }

    }

}
编辑:根据tyczj的回答,我不需要asynctask,愚蠢的我。这是工作版本:

public class TaskService extends IntentService {

private ArrayList<BloodLevels> BloodLevelList;

private String bloodLevel;
private String bloodType;
private Integer bloodLevelDays;

public TaskService() {
    super("TaskService");
}

@Override
protected void onHandleIntent(Intent intent) {

    // Pass through the blood type from AlarmReceiver
    Bundle bundle = intent.getExtras();
    bloodType = bundle.getString("currentBloodType2");

    // Only perform check if there is an internet connection
    if (CheckNetwork.isInternetAvailable(TaskService.this)) {

        try {

            // HTTP PROTOCOL
            Document doc = Jsoup
                    .connect(
                            "http://www.giveblood.ie/Current_Blood_Supply/")
                    .timeout(5000)
                    .userAgent(
                            "Mozilla/5.0 (Windows; U; WindowsNT 5.1; en-US; rv1.8.1.6) Gecko/20070725 Firefox/2.0.0.6")
                    .cookie("auth", "token").get();

            // EXTRACT SPECIFIC ELEMENTS FROM THE HTML
            Elements bloodsupplylines1 = doc.select("td.bloodsupplyline");
            Elements bloodsupplylines2 = bloodsupplylines1
                    .select("img[src~=(?i)\\.(png|jpe?g|gif)]");

            // CREATE LIST AND POPULATE IT WITH ELEMENTS RETRIEVE FROM HTML
            List<String> BloodLevelRawList = new ArrayList<String>();

            for (Element bloodsupplyline : bloodsupplylines2) {

                BloodLevelRawList.add(new String(bloodsupplyline
                        .attr("alt")));

            }

            BloodLevelList = new ArrayList<BloodLevels>();

            for (int i = 0; i < BloodLevelRawList.size(); i += 2) {
                // Only add to BloodLevelList if it is the blood type
                // selected
                if (BloodLevelRawList.get(i).equals(bloodType)) {

                    BloodLevelList.add(new BloodLevels(BloodLevelRawList
                            .get(i), BloodLevelRawList.get(i + 1)));
                }
            }

        }

        catch (IOException ioex) {
            ioex.printStackTrace();
        }

        String bloodLevelReplace = BloodLevelList.get(0).getBloodLevel()
                .replaceAll("Blood supply", "");

        bloodLevel = ("Current blood levels for "
                + BloodLevelList.get(0).getBloodType() + " is" + bloodLevelReplace);

        // Get the number of days from the blood level string
        Scanner in = new Scanner(bloodLevel).useDelimiter("[^0-9]+");
        int bloodLevelDays = in.nextInt();

        // Send notification if no. of days blood level supply goes below 5
        if (bloodLevelDays < 5) {

            this.sendNotification(this);

        }

    } else {
        Toast.makeText(
                TaskService.this,
                "Unable to perform daily blood level check, no internet connection.",
                Toast.LENGTH_LONG).show();
    }

}

private void sendNotification(Context context) {

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
            this).setSmallIcon(R.drawable.ic_launcher)
            .setContentTitle("Blood Level Notification")
            .setContentText(bloodLevel);

    Intent resultIntent = new Intent(this, MyProfileActivity.class);

    // Because clicking the notification opens a new ("special") activity,
    // there's no need to create an artificial back stack.
    PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0,
            resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    mBuilder.setContentIntent(resultPendingIntent);

    // Sets an ID for the notification
    int mNotificationId = 001;
    // Gets an instance of the NotificationManager service
    NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    // Builds the notification and issues it.
    mNotifyMgr.notify(mNotificationId, mBuilder.build());

}

}

1 个答案:

答案 0 :(得分:5)

为什么你在AsyncTask使用IntentServiceIntentService已经在一个单独的线程上运行,所以使用AsyncTask不是nesaccery。

由于IntentService来自Context,所有你需要做的就是致电TaskService.this而你有上下文