1

を使用して Web から画像をダウンロードする プログラムを作成しました。ダウンロードプロセスは正常に機能します。ダウンロードの進行状況を示すために を使用しています。また、ダウンロードを開始するボタンとダウンロードを停止するボタンが 2 つあります。しかし、停止ボタンをクリックしても、進行中のダウンロードを停止できません。通知マネージャーは同じことを続けます。AsyncTaskservicenotification

主な活動:

public class ServicedownloadActivity extends Activity implements
        OnClickListener {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        b1 = (Button) findViewById(R.id.button1);
        b2 = (Button) findViewById(R.id.button2);
        b1.setOnClickListener(this);
        b2.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        if (v.getId() == R.id.button1) {
            Intent intent = new Intent(ServicedownloadActivity.this,
                    Myclass.class);
            startService(intent);

        }
        if (v.getId() == R.id.button2) {

            Intent intent = new Intent(ServicedownloadActivity.this,
                    Myclass.class);
            stopService(intent);
        }
    }
}

クラスにはサービスと asynchTask が含まれます

public class Myclass extends Service {

    URLConnection connection;
    private final Random mGenerator = new Random();

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

    public int getRandomNumber() {
        return mGenerator.nextInt(100);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("df", "From oncreate");
        Toast.makeText(this, "on create", Toast.LENGTH_SHORT).show();

    }
    class DownloadWebPageTask extends AsyncTask<String, String, String> {
        String responseTextt;
        NotificationManager notificationManager;
        Notification notification;
        CharSequence contentText;
        Context context;
        CharSequence contentTitle;
        PendingIntent contentIntent;
        int HELLO_ID = 1;
        long time;
        int icon;
        CharSequence tickerText;

        public void downloadNotification() {
            String ns = Context.NOTIFICATION_SERVICE;
            notificationManager = (NotificationManager) getSystemService(ns);
            icon = R.drawable.ic_launcher;
            tickerText = "Downloading...";
            time = System.currentTimeMillis();
            notification = new Notification(icon, tickerText, time);
            context = getApplicationContext();
            contentTitle = "Your download is in progress";
            contentText = "0% complete";
            Intent notificationIntent = new Intent(Intent.ACTION_VIEW);
            notificationIntent.setType("audio/*");
            contentIntent = PendingIntent.getActivity(context, 0,
                    notificationIntent, 0);
            notification.setLatestEventInfo(context, contentTitle,
                    contentText, contentIntent);
            notificationManager.notify(HELLO_ID, notification);

        }

        @Override
        protected String doInBackground(String... urls) {

            try {

                Log.d("trys:", "try");
                URL url = new URL(
                        "http://www.zapiture.com/resources/IMG_6812.JPG");
                connection = url.openConnection();
                connection.connect();
                int fileLength = connection.getContentLength();
                InputStream input = new BufferedInputStream(url
                        .openStream());
                OutputStream output = new FileOutputStream(Environment
                        .getExternalStorageDirectory()
                        + "/img23.jpg");

                byte data[] = new byte[1024];
                long total = 0;
                int count;
                int previousProgress = 0;
                while ((count = input.read(data)) != -1) {
                    total += count;
                    if ((int) (total * 100 / fileLength) > previousProgress) {
                        previousProgress = (int) (total * 100 / fileLength);
                        publishProgress(""
                                + (int) (total * 100 / fileLength));
                        output.write(data, 0, count);
                    }
                }

                output.flush();
                output.close();
                input.close();

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

            return null;
        }

        @Override
        protected void onPreExecute() {
            downloadNotification();

            super.onPreExecute();
            ;
        }

        @Override
        public void onProgressUpdate(String... progress) {

            contentText = Integer.parseInt(progress[0]) + "% complete";
            notification.setLatestEventInfo(context, contentTitle,
                    contentText, contentIntent);
            notificationManager.notify(HELLO_ID, notification);
            super.onProgressUpdate(progress);
        }
    }

    @Override
    public void onStart(Intent intent, int startId) {
        // TODO Auto-generated method stub
        super.onStart(intent, startId);
        Log.d("sf", "On Start");
        Toast.makeText(this, "on start", Toast.LENGTH_SHORT).show();
        DownloadWebPageTask task = new DownloadWebPageTask();

        task.execute();
    }

    @Override
    public void onDestroy() {
        stopSelf();
        super.onDestroy();
        Log.d("df", "From on Destroy");
        Toast.makeText(this, "on destroy", Toast.LENGTH_SHORT).show();
    }
}
4

4 に答える 4

1

AsyncTaskあなたは本当にサービスで使うべきではありません、それは活動で使うためです。ワーカースレッドを自動的に開始するサービスが必要な場合は、を使用してIntentServiceください。また、完了すると自動的に停止します。進捗状況の更新を送信するには、さらに作業が必要になる場合がありますが、よりもはるかにクリーンになりますAsyncTask

于 2012-06-18T05:40:26.103 に答える
0

stopServiceを呼び出しても、処理の途中でAsyncTaskが停止しないことを常に覚えておいてください。サービスのonDestroyの実装でタスクのcancelメソッドを呼び出さない限り、AsyncTaskは完了すると終了します。

したがって、コードで次の変更を行います。

基本的にこれを追加する必要があります。

@Override
public void onDestroy() {
    task.canel();
    super.onDestroy();
}

またDownloadWebPageTask task = new DownloadWebPageTask();、開始時に内部を作成しているため、onDestroyでtask.cancelを呼び出すことはできません。むしろ、DownloadWebPageTask task; 外部で定義して、で使用task.cancelできるようにしonDestroyます。

于 2012-06-18T05:38:08.080 に答える
0

Boolean最初にフラグ変数を作成し、変更true中に次のようにすることをお勧めしますonDestroy()false

true の場合は変数ステータスをdoInBackground確認し、false の場合はタスクを続行し、それを停止して呼び出すだけですreturn;

AsyncTask別々に実行されるprocessため、アクティビティ/サービスが破壊された場合でも、実行を続けます。

于 2012-06-18T06:51:41.650 に答える
0

ダウンロードに使用AsyncTaskしているため、AsyncTask 自体をキャンセルしてみることができますcancel(boolean)

task.cancel(true);
于 2012-06-18T05:25:50.880 に答える