14

私は画像ビューを持っています、私はスワイプを書いていました、そのスワイプの時点で、画像はインターネットからダウンロードされているので、スワイプする前にバックグラウンドで画像をダウンロードする必要があると思いました. IntentService、これらはすべて data/data/mypackages にダウンロードして保存するのに役立ちますが、私の場合はスワイプが遅くなり、どのアイデアが最適かを教えてくれます。正しい方法で呼び出していますか

1.非同期タスク

2. サービス

3.以下に示すインテントサービス、

まだ私の問題が解決されていないため、どちらが正しい方法であるか混乱しています

asynctask コード サンプル スニペットは次のとおりです。

public class Demo extends Activity {

  @Override

  public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

       new FirstTask().execute(); // calling Asynctask here

  }

}

非同期タスク コード

private class FirstTask extends AsyncTask<Void, Void, Void> {
        private final ProgressDialog dialog = new ProgressDialog(Catalogue.this);
        int temp = 0;

        // can use UI thread here
        protected void onPreExecute() {
            this.dialog.setMessage("Loading...");
            this.dialog.setCancelable(false);
            //this.dialog.show();
            System.gc();
            Toast.makeText(Catalogue.this, "My Async  Created",
                    Toast.LENGTH_LONG).show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            Looper.prepare();  
            try {

                myddownloadmethod();// calling my download method

            } catch (Exception e) {
                Util.trace("Error in Async"+e.getMessage());

            }
              Looper.loop();

            return null;
        }

        protected void onPostExecute(Void result) {

            if (this.dialog.isShowing()) {
                Toast.makeText(Catalogue.this, "My Async destroyed",
                        Toast.LENGTH_LONG).show();
                Toast.makeText(Catalogue.this, "count" + temp,
                        Toast.LENGTH_LONG).show();
                this.dialog.dismiss();
            }
        }
    }

これが私のサービスのシンペットです

public class MyService extends Service implements Runnable

{      @Override

        public void onCreate() {

                super.onCreate();

                Thread mythread = new Thread(this);

                mythread.start();

        }



        public void run() {

                Looper.prepare();  

                try {

                        myddownloadmethod();// calling my download method

                } catch (Exception e1) {

                        // TODO Auto-generated catch block

                        e1.printStackTrace();

                }

                Looper.loop();

        }



        @Override
        public IBinder onBind(Intent intent) {

                // TODO Auto-generated method stub

                return null;

        }



}



Invoking Service  

public class ServicesDemo extends Activity {    

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

      startService(new Intent(this, MyService.class));


  }

}

これがIntentServiceコードです

public class Downloader extends IntentService {

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

    @Override
    public void onCreate() {
        super.onCreate();


    }

    @Override
    public void onDestroy() {
        super.onDestroy();

            }

    @Override   
    public void onHandleIntent(Intent i) {

        try {
             myddownloadmethod();// calling my download method
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            Log.d("Error",e1.getMessage());
        }

    }
}

MyActivity から IntentService を呼び出す

public class ServicesDemo extends Activity {    
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Intent i1=new Intent(this, Downloader.class);
        startService(i1);



      }

    }
4

5 に答える 5

17

サーバーからファイルをダウンロードしてSDカードに入れるために行ったように、サービスを使用してダウンロードする最良の方法は、通知も使用します。かなり長いコードですが、完璧なコードだと思います。何かわからないことがあれば、android 開発者ブログでサービスを確認してください。

public class DownloadService extends Service{

     SharedPreferences preferences;

    private static final String DOCUMENT_VIEW_STATE_PREFERENCES = "DjvuDocumentViewState";

      private Looper mServiceLooper;
      private ServiceHandler mServiceHandler;
      private NotificationManager mNM;
      String downloadUrl;
      public static boolean serviceState=false;

      // Handler that receives messages from the thread
      private final class ServiceHandler extends Handler {
          public ServiceHandler(Looper looper) {
              super(looper);
          }
          @Override
          public void handleMessage(Message msg) {
              downloadFile();
              showNotification(getResources().getString(R.string.notification_catalog_downloaded),"VVS");
              stopSelf(msg.arg1);
          }
      }


    @Override
        public void onCreate() {
            serviceState=true;
            mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
            HandlerThread thread = new HandlerThread("ServiceStartArguments",1);
            thread.start();

            // Get the HandlerThread's Looper and use it for our Handler 
            mServiceLooper = thread.getLooper();
            mServiceHandler = new ServiceHandler(mServiceLooper);

        }



     @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
             Log.d("SERVICE-ONCOMMAND","onStartCommand");  

               Bundle extra = intent.getExtras();
               if(extra != null){
                   String downloadUrl = extra.getString("downloadUrl");
                   Log.d("URL",downloadUrl);

                   this.downloadUrl=downloadUrl;
               }

              Message msg = mServiceHandler.obtainMessage();
              msg.arg1 = startId;
              mServiceHandler.sendMessage(msg);

              // If we get killed, after returning from here, restart
              return START_STICKY;
          }



     @Override
          public void onDestroy() {

             Log.d("SERVICE-DESTROY","DESTORY");
             serviceState=false;
            //Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show(); 
          }


     @Override
      public IBinder onBind(Intent intent) {
          // We don't provide binding, so return null
          return null;
      }


      public void downloadFile(){

            downloadFile(this.downloadUrl,fileName);


      }



        void showNotification(String message,String title) {
        // In this sample, we'll use the same text for the ticker and the expanded notification
        CharSequence text = message;

        // Set the icon, scrolling text and timestamp
       Notification notification = new Notification(R.drawable.icon, "vvs",
                System.currentTimeMillis());
        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        Intent intent = new Intent(this, HomeScreenActivity.class);
        intent.setFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP);
         //The PendingIntent to launch our activity if the user selects this notification
        PendingIntent contentIntent = PendingIntent.getActivity(this.getBaseContext(), 0,
              intent, PendingIntent.FLAG_CANCEL_CURRENT);

        // Set the info for the views that show in the notification panel.
        notification.setLatestEventInfo(this, title,
                      text, contentIntent);
        // Send the notification.
        // We use a layout id because it is a unique number.  We use it later to cancel.
        mNM.notify(R.string.app_name, notification);
    }

  public void downloadFile(String fileURL, String fileName) {

    StatFs stat_fs = new StatFs(Environment.getExternalStorageDirectory().getPath());
    double avail_sd_space = (double)stat_fs.getAvailableBlocks() *(double)stat_fs.getBlockSize();
    //double GB_Available = (avail_sd_space / 1073741824);
    double MB_Available = (avail_sd_space / 10485783);
    //System.out.println("Available MB : " + MB_Available);
    Log.d("MB",""+MB_Available);
   try {
        File root =new File(Environment.getExternalStorageDirectory()+"/vvveksperten");
        if(root.exists() && root.isDirectory()) {

        }else{
            root.mkdir();
        }
        Log.d("CURRENT PATH",root.getPath());
        URL u = new URL(fileURL);
        HttpURLConnection c = (HttpURLConnection) u.openConnection();
        c.setRequestMethod("GET");
        c.setDoOutput(true);
        c.connect();
          int fileSize  = c.getContentLength()/1048576;
          Log.d("FILESIZE",""+fileSize);
          if(MB_Available <= fileSize ){
               this.showNotification(getResources().getString(R.string.notification_no_memory),getResources().getString(R.string.notification_error));
              c.disconnect();
              return;
          } 

        FileOutputStream f = new FileOutputStream(new File(root.getPath(), fileName));

        InputStream in = c.getInputStream();


        byte[] buffer = new byte[1024];
        int len1 = 0;
        while ((len1 = in.read(buffer)) > 0) {
            f.write(buffer, 0, len1);
        }
        f.close();
        File file = new File(root.getAbsolutePath() + "/" + "some.pdf");
        if(file.exists()){
            file.delete();
            Log.d("FILE-DELETE","YES");
        }else{
            Log.d("FILE-DELETE","NO");
        }
        File from =new File(root.getAbsolutePath() + "/" + fileName);
        File to = new File(root.getAbsolutePath() + "/" + "some.pdf");


        } catch (Exception e) {
        Log.d("Downloader", e.getMessage());

    }
于 2011-06-13T05:02:55.960 に答える
3

後でこの質問に出くわした人は、プロジェクトの Android サンプル コードで使用されている非同期ダウンロード メカニズムを見てくださいcom.example.android.bitmapfun.ui.ImageGridActivity。画像を非同期的にダウンロードし、ImageView でオフライン表示するために画像をキャッシュします。人々はこのコードをラップして、独自の画像読み込みライブラリを作成しました。これらのライブラリは、サービスの代わりに AsyncTask を使用します。非同期タスクは、数秒以内に作業を終了することが期待されています。

より大きなものをダウンロードする場合は、サービスを使用する代わりに、API 9 以降で利用できるDownloadManagerをお勧めします。そこには、ダウンロードに回復力を追加する多くのコードがあります。

ダウンロード マネージャーは、長時間実行される HTTP ダウンロードを処理するシステム サービスです。クライアントは、特定の宛先ファイルに URI をダウンロードするように要求する場合があります。ダウンロード マネージャーはバックグラウンドでダウンロードを実行し、HTTP インタラクションを処理し、障害発生後または接続の変更やシステムの再起動後にダウンロードを再試行します。このクラスのインスタンスは、DOWNLOAD_SERVICE を渡して getSystemService(String) を介して取得する必要があります。この API を介してダウンロードを要求するアプリは、ACTION_NOTIFICATION_CLICKED のブロードキャスト レシーバーを登録して、ユーザーが通知またはダウンロード UI から実行中のダウンロードをクリックしたときに適切に処理する必要があります。このクラスを使用するには、アプリケーションに INTERNET 権限が必要であることに注意してください。

于 2013-03-26T12:46:58.400 に答える
2

あなたはおそらくこれを設計しすぎています。画像を動的にロードするスワイプを実装しました。静的メソッド呼び出しを介してすべてを実行する単純なユーティリティ クラスを使用するだけです。このクラスを試してください:

package com.beget.consumer.util;

/*
 Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.    
*/
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ImageView;

public class DrawableLoader {
    private final Map<String, Drawable> drawableMap;
    private WeakReference<ImageView> imageViewReference;

    public DrawableLoader() {
        drawableMap = new HashMap<String, Drawable>();
    }

    public Drawable fetchDrawable(String urlString) {
        if (drawableMap.containsKey(urlString)) {
            return drawableMap.get(urlString);
        }

        Log.d(this.getClass().getSimpleName(), "image url:" + urlString);
        try {
            InputStream is = fetch(urlString);
            Drawable drawable = Drawable.createFromStream(is, "src");
            drawableMap.put(urlString, drawable);
            Log.d(this.getClass().getSimpleName(), "got a thumbnail drawable: " + drawable.getBounds() + ", "
                    + drawable.getIntrinsicHeight() + "," + drawable.getIntrinsicWidth() + ", "
                    + drawable.getMinimumHeight() + "," + drawable.getMinimumWidth());
            return drawable;
        } catch (MalformedURLException e) {
            Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
            return null;
        } catch (IOException e) {
            Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
            return null;
        }
    }

    public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {

        imageViewReference = new WeakReference<ImageView>(imageView);

        if (drawableMap.containsKey(urlString)) {
            imageViewReference.get().setImageDrawable(drawableMap.get(urlString));
        }

        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message message) {
                imageViewReference.get().setImageDrawable((Drawable) message.obj);
            }
        };

        Thread thread = new Thread() {
            @Override
            public void run() {
                //TODO : set imageView to a "pending" image
                Drawable drawable = fetchDrawable(urlString);
                Message message = handler.obtainMessage(1, drawable);
                handler.sendMessage(message);
            }
        };
        thread.start();
    }

    private InputStream fetch(String urlString) throws MalformedURLException, IOException {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet request = new HttpGet(urlString);
        HttpResponse response = httpClient.execute(request);
        return response.getEntity().getContent();
    }

}

必要なのはこれだけです。次に、画像をロードする必要がある場合は、次のように呼び出します。

fetchDrawableOnThread("http://path/to/your/image.jpg", yourImageViewReference);

それでおしまい。
JSON オブジェクトから URL を取得した場合は、URL を解析して文字列に変換します。
String url = jsonObj.getString("url"); 次に、次のように呼び出します。fetchDrawableOnThread(url, yourImageViewReference);

于 2011-06-10T10:03:58.533 に答える