在Android上使用后台服务下载数据-一些一般问题

在Android上使用后台服务下载数据-一些一般问题,android,arraylist,download,queue,background-service,Android,Arraylist,Download,Queue,Background Service,谈到Android上的后台服务,我有一些理解上的问题。我有一种感觉,对于你们这些有着丰富经验的人来说,我的问题很容易回答,我只需要被指向正确的方向:-) 首先让我解释一下我想要实现的目标: 我想下载带有一组数据的图片(下载url、标题、ID、所有者ID和文件名)。用户通过文本字段输入该数据。用户可以输入该数据集的多个实体,因此所有内容都存储在ArrayList中。例如,URL有一个ArrayList,ID有一个ArrayList。 从长远来看,这些信息不应该来自用户,而是来自服务器。用户界面基本

谈到Android上的后台服务,我有一些理解上的问题。我有一种感觉,对于你们这些有着丰富经验的人来说,我的问题很容易回答,我只需要被指向正确的方向:-)

首先让我解释一下我想要实现的目标: 我想下载带有一组数据的图片(下载url、标题、ID、所有者ID和文件名)。用户通过文本字段输入该数据。用户可以输入该数据集的多个实体,因此所有内容都存储在ArrayList中。例如,URL有一个ArrayList,ID有一个ArrayList。 从长远来看,这些信息不应该来自用户,而是来自服务器。用户界面基本上只是用于调试。 下载完成后,将数据集放入SQLite数据库中

我的目标是拥有一个独立的后台服务,负责下载并在下载完成后立即将数据插入数据库。 因此,从用户输入数据的活动中,我创建了一个意图,并将用户数据作为额外数据添加。第一个问题是:没有额外的ArrayList。这引出了我的第一个问题:

如何在服务/活动之间传递ArrayList? 我读过一些关于包裹的文章,尽管long是一种原始数据类型,但这是一种方法吗

我的第二个问题是,在再次调用服务之前,我无法确定下载是否完成。因此,当再次调用服务时,将再次调用onStartCommand()方法。现在我的服务类如下所示(ArrayList中的数据尚未实现):

公共类DownloadService扩展服务实现DownloadAlbumPictures.DownloadCompletedListener{
公共最终静态字符串EXTRA\u ALBUMPICTURE\u URL=“ALBUM\u PICTURE\u URL”;
公共最终静态字符串EXTRA\u ALBUMPICTURE\u NAMES=“ALBUM\u PICTURE\u NAMES”;
公共最终静态字符串EXTRA\u ALBUMPICTURE\u TITLES=“ALBUM\u PICTURE\u TITLES”;
私有数组列表;
文件的私有ArrayList名称;
私有ArrayList所有者ID;
私人ArrayList pictureIds;
私有ArrayList AlbumID;
私人ArrayList职位;
私人ArrayList头衔;
私有字符串路径文件;
//下载接口
public void albumPicDownloadCompleted(上下文上下文、Uri、int indexOfCompletedFile){
//初始化
相册图片新相册图片;
//下载数据
long ownerId=0//ownerId.get(indexOfCompletedFile);
long pictureId=0//pictureId.get(indexOfCompletedFile);
int positionInAlbum=0//positions.get(indexOfCompletedFile);
字符串标题=titles.get(indexOfCompletedFile);
字符串pathToPic=uri.toString();
long albumId=0//albumId.get(indexOfCompletedFile);
newAlbumPic=新的AlbumPicture(所有者ID、pictureId、位置栏、标题、路径主题、albumId);
//将图片放入数据库
newAlbumPic.putinodb(本);
}
@凌驾
公共int onStartCommand(Intent Intent、int标志、int startId){
picUrls=intent.getStringArrayListExtra(额外的图片URL);
namesForFiles=intent.getStringArrayListExtra(额外的图片名称);
titles=intent.getStringArrayListExtra(额外的图片标题);
DownloadAlbumPictures dwnldAlbumPics=新下载的AlbumPictures(newPicUrls、newNamesForFiles);
dwnldAlbumPics.execDownload(this);
返回服务。启动\u重新交付\u意图;
}
}
DownloadAlbumPictures.execDownload调用Androids下载管理器。它还为下载完成事件注册广播接收器,然后调用接口函数albumPicDownloadCompleted():

公共类下载相册图片{
公共接口下载CompletedListener{
public void albumPicDownloadCompleted(上下文上下文、Uri、int indexOfCompletedFile);
}
私有数组列表;
文件的私有ArrayList名称;
私有ArrayList下载引用;
私有字符串路径文件;
私有下载CompletedListener dwnldCompletedListener;
公开下载相册图片(ArrayList\u picUrls、ArrayList\u namesForFiles){
picUrls=_picUrls;
namesForFiles=_namesForFiles;
}
公众下载相册图片(){
}
公共布尔执行下载(上下文){
//检查源信息是否可用
if(picUrls==null | | namesForFiles==null)
返回false;
获取图片(上下文);
返回true;
}
public boolean execDownload(上下文上下文、ArrayList\u picUrls、ArrayList\u namesForFiles){
picUrls=_picUrls;
namesForFiles=_namesForFiles;
返回execDownload(上下文);
}
//示例用于下载图片
私有void fetchPics(上下文){
//路径
pathToFiles=CreatePathForalPumpictures();
//侦听器接口
试一试{
dwnldCompletedListener=(DownloadCompletedListener)上下文;
}catch(ClassCastException e){
抛出新的ClassCastException(context.toString()+“必须为AlbumPicture下载实现DownloadCompletedListener。”);
}
//将文件发送到下载管理器并保存引用
//TODO文件类型检查丢失=>安全问题
DownloadFiles DownloadFiles=新的下载文件(picurl、pathToFiles、namesForFiles);
if(downloadFiles.startDownload(上下文)){
downloadReferences=downloadFiles.getDownloadReferences();
}
否则{
downloadReferences=null;
}
//为文件下载完成时添加侦听器
IntentFilter broadcastFilter=新的IntentFilter(DownloadManager.ACTION\u DOWNLOAD\u COMPLETE);
BroadcastReceiver=新的BroadcastReceiver(){
@凌驾
公共void onReceive(上下文、意图){
long reference=intent.getlongtextra(DownloadManager.EXTRA_DOWNLOAD_ID,-1);//获取已完成的
public class DownloadService extends Service implements DownloadAlbumPictures.DownloadCompletedListener {

    public final static String EXTRA_ALBUMPICTURE_URLS = "ALBUM_PICTURE_URLS";
    public final static String EXTRA_ALBUMPICTURE_NAMES = "ALBUM_PICTURE_NAMES";
    public final static String EXTRA_ALBUMPICTURE_TITLES = "ALBUM_PICTURE_TITLES";

    private ArrayList<String> picUrls;
    private ArrayList<String> namesForFiles;
    private ArrayList<Long> ownerIds;
    private ArrayList<Long> pictureIds;
    private ArrayList<Long> albumIds;
    private ArrayList<Integer> positions;
    private ArrayList<String> titles;
    private String pathToFiles;

    // download interface
     public void albumPicDownloadCompleted(Context context, Uri uri, int indexOfCompletedFile) {
         // init
          AlbumPicture newAlbumPic;

         // data from download
          long ownerId = 0 //ownerIds.get(indexOfCompletedFile);
          long pictureId = 0 //pictureIds.get(indexOfCompletedFile);
          int positionInAlbum = 0 //positions.get(indexOfCompletedFile);
          String title = titles.get(indexOfCompletedFile);
          String pathToPic = uri.toString();
          long albumId = 0 //albumIds.get(indexOfCompletedFile);

          newAlbumPic = new AlbumPicture(ownerId, pictureId, positionInAlbum, title, pathToPic, albumId);

         // put picture into DB
          newAlbumPic.putIntoDb(this);
     }

    @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
         picUrls = intent.getStringArrayListExtra(EXTRA_ALBUMPICTURE_URLS);
         namesForFiles = intent.getStringArrayListExtra(EXTRA_ALBUMPICTURE_NAMES);
         titles = intent.getStringArrayListExtra(EXTRA_ALBUMPICTURE_TITLES);

          DownloadAlbumPictures dwnldAlbumPics = new DownloadAlbumPictures(newPicUrls, newNamesForFiles);
          dwnldAlbumPics.execDownload(this);
          return Service.START_REDELIVER_INTENT;
     }
}
public class DownloadAlbumPictures {

public interface DownloadCompletedListener {
    public void albumPicDownloadCompleted(Context context, Uri uri, int indexOfCompletedFile);
}

private ArrayList<String> picUrls;
private ArrayList<String> namesForFiles;
private ArrayList<Long> downloadReferences; 
private String pathToFiles;

private DownloadCompletedListener dwnldCompletedListener;

public DownloadAlbumPictures(ArrayList<String> _picUrls, ArrayList<String> _namesForFiles) {
    picUrls = _picUrls;
    namesForFiles = _namesForFiles;
}

public DownloadAlbumPictures() {

}

public boolean execDownload(Context context) {
    // check if source info is available
    if (picUrls == null || namesForFiles == null)
        return false;

    fetchPics(context);
    return true;
}

public boolean execDownload(Context context, ArrayList<String> _picUrls, ArrayList<String> _namesForFiles) {
    picUrls = _picUrls;
    namesForFiles = _namesForFiles;

    return execDownload(context);
}

// example use to download pictures
private void fetchPics(Context context) {
    // path
    pathToFiles = createPathForAlbumPictures();
    // listener interface
    try {
        dwnldCompletedListener = (DownloadCompletedListener) context;
    } catch (ClassCastException e) {
        throw new ClassCastException(context.toString() + " must implement DownloadCompletedListener for AlbumPicture download.");
    }

    // sending files to download manager and saving reference
    // TODO file type check missing => security issue
    DownloadFiles downloadFiles = new DownloadFiles(picUrls, pathToFiles, namesForFiles);
    if (downloadFiles.startDownload(context)) {
        downloadReferences = downloadFiles.getDownloadReferences();
    }
    else {
        downloadReferences = null;
    }
    // add listeners for when file download is completed
    IntentFilter broadcastFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
    BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            long reference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);    // get reference of completed download (if no completed download -1)
            // check all downloaded files
            for (int i=0; i<downloadReferences.size(); i++) {
                if (reference == downloadReferences.get(i)) {
                    // actual path to file needs to be updated
                    DownloadManager dwnldmngr = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
                    Uri uriOfFile = dwnldmngr.getUriForDownloadedFile(reference);
                    // hand over uri to interface
                    dwnldCompletedListener.albumPicDownloadCompleted(context, uriOfFile, i);    // interface
                }
            }
        }
    };
    context.registerReceiver(receiver, broadcastFilter);
}
}