DownloadManager冻结ui

时间:2016-05-27 09:56:14

标签: android

我尝试使用DownloadManager加载多个文件(100+),同时将文件网址应用冻结,同时下载文件应用程序确实滞后。

    DownloadManager downloadManager = ( DownloadManager ) context.getSystemService( Context.DOWNLOAD_SERVICE );
    DownloadManager.Request request;

    long[] ids = new long[ tiles.size() ];
    int cpt = 0;

    for ( MapUtils.Tile tile : tiles )
    {
        String path = "/tiles/" + provider.getId() + "/" + tile.getZ() + "/" + tile.getX() + "/" + tile.getY() + ".jpg";
        File file = new File( context.getExternalFilesDir( null ) + path );

        Log.d( "MapUtils", "download " + file.getPath() + " --- " + file.exists() );

        if ( file.exists() ) file.delete();

        request = new DownloadManager.Request( Uri.parse( tile.getUrl( provider.getUrl() ) ) );
        request.setAllowedNetworkTypes( DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE );
        request.setAllowedOverRoaming( false );
        request.setVisibleInDownloadsUi( false );
        request.setTitle( tile.getUrl( provider.getUrl() ) );
        request.setNotificationVisibility( DownloadManager.Request.VISIBILITY_HIDDEN );
        request.setDestinationInExternalFilesDir( context, null, path );
        ids[ cpt ] = downloadManager.enqueue( request );
        cptt+

    }

用于循环冻结应用程序,需要一段时间才能将所有文件排入队列

    BroadcastReceiver receiver = new BroadcastReceiver()
    {
        @Override
        public void onReceive( Context context, Intent intent )
        {
            DownloadManager manager = ( DownloadManager ) getSystemService( Context.DOWNLOAD_SERVICE );
            String action = intent.getAction();
             Log.d( "BroadcastReceiver", "action " + action );
            if ( DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals( action ) )
            {
                long downloadId = intent.getLongExtra(
                        DownloadManager.EXTRA_DOWNLOAD_ID, 0 );
                DownloadManager.Query query = new DownloadManager.Query();
                 Log.d( "BroadcastReceiver", "downloadId" + downloadId + " - " + manager.getUriForDownloadedFile( downloadId ) );

                Cursor c = manager.query( query );
                if ( c.moveToFirst() )
                {
                    int columnIndex = c
                            .getColumnIndex( DownloadManager.COLUMN_STATUS );
                    if ( DownloadManager.STATUS_SUCCESSFUL == c
                            .getInt( columnIndex ) )
                    {
                        Log.d( "BroadcastReceiver", "complete" );
                    }
                }
                c.close();
            }
        }
    };

    registerReceiver( receiver , new IntentFilter(
            DownloadManager.ACTION_DOWNLOAD_COMPLETE ) );

在所有文件入队后,我开始接收完整的回调,应用程序不再完全冻结,但非常滞后。

我看到DownloadManager正在后台执行,所以我没有得到它。 谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

这里有很多东西可以减慢您的应用:

  • 为每个文件创建一个新BroadcastReceiver并注册它。这导致新的对象创建和Cris进程与框架的通信,两者都很昂贵。
  • 删除循环中的文件。文件I / O和种类很慢,因此可能会导致延迟。
  • Cursor方法中使用onReceive()。这是另一个可能很昂贵的处理呼叫。 DownloadManager在另一个进程中,因此查询将进行跨进程,并且游标操作通常很慢。

要做的事情:

  • 使用单个BroadcastReceiver来处理来自DownloadManager
  • 的回复
  • 不查询DownloadManager以处理已完成的文件。 id中的Intent告诉您哪个文件已完成,如果您需要更多状态信息并采取操作,请使用某种类型的延迟处理,如线程。
  • 如果您不需要重新下载文件,请不要删除现有文件并强行重新下载