android程序---->android多线程下载(一)

  多线程下载是加快下载速度的一种方式,通过开启多个线程去执行一个任务,可以使任务的执行速度变快。多线程的任务下载时常都会使用得到断点续传下载,就是我们在一次下载未结束时退出下载,第二次下载时会接着第一次下载的进度继续下载。对于android中的下载,我想分多个部分去讲解分析。今天,我们就首先开始android中下载断点续传代码的实现。源码下载:java多线程断点续传(一)。关于多线程下载单个文件的实现,请参见博客:android程序---->android多线程下载(二)

目录导航

  1. android中断点续传的思路
  2. android断点续传基本的UI
  3. android断点续传的工具类
  4. 下载暂停取消的具体流程
  5. 友情链接

android中断点续传的思路

一、 断点续传的实现步骤:

第一步: 我们要获得下载资源的的长度,用http请求中HttpURLConnection的getContentLength()方法

第二步:在本地创建一个文件,设计其长度。File file = new File()

第三步:从数据库中获得上次下载的进度,当暂停下载时,存储下载的状态,用到数据库的知识

第四步:从上次下载的位置下载数据,同时保存进度到数据库:RandomAccessFile的seek方法与HttpURLConnection的setRequestProperty方法

第五步:将下载进度回传到Activity,可以通过Intent将数据广播到Activity中

第六步:下载完成后删除下载信息,在数据库中删除相应的信息

二、 断点续传实现的流程图:

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAh0AAAEiCAIAAADSxvdVAAAgAElEQVR4nOydd2BO1//Hz09VUVW0ur5fqiUkNiFWCFlGrditLv1aESQ1a9ZWm9irVmlsYkVRxN57RG21JSLjGffecz6/Pz65x830SMKTRz6vXunz3OfOc879vM/5nM85lwmCsAHOORCODOfc3oWIyC4we18A4RiQrjg6pCvEa4N0hbAJ0hVHh3SFeG2QrhA2Qbri6JCuEK8N0hXCJkhXHB3SFeK1QbpC2ATpiqNDukK8NkhXCJsgq+ToUA4Srw3SFcJWOOHI2Lv4ENkI0hWCIAgiMyFdIQiCIDIT0hWCIAgiMyFdIQiCIDIT0hWCIAgiMyFdIQiCIDIT0hWCIAgiMyFdIQiCIDIT0hWCIAgiM0mnrtDwXYIgELIGRBLSoyucc5zGTlVVkXh6D40giOwE2gRFUTLTLBEOTjrbKyaTCSspiqLQHEQEkT3RNE1RFACw94UQWYt06oqiKGazGcuTnaf/JgjCrphMJiBpIQyk3w+mquqFCxf8/f276/To0cPf378bQRDZA39//969ew8cONDX15ekhZCks72iaRoALFq06J9//rFvXYkgCLvTtWtXIF0hdDKkK8uWLTtz5gyVJ4LInmiaht6LTp06kR0gJKQrBEGkE9IVIkVIV4ishZ0cOcSLSZ5ZpCtEipCuEFkILFRdunQJCgrCSBDC7gQEBPTv33/FihUAYLFYjPlFukKkCOkKkYUAvQeYyGr07NkTAOLj4435RbpCpAjpyhsET/otxSUrAwBdunQBADmQm8gKAIC/vz8KjHH4M+kKkSKkK4ngNpApZ0nj60sfDdWCP/+Stn6kpjf2WowAQI8ePQDAYrEknzKEJgqyFwAQFBSUXO810hUiJbKprlitVs651WrF+hcaLBw2/EJSkwFFUUwmk8lk0tKsa1ssFkwxnAAjLi4ujWO+EC4EaAKE4CAUECoIDgJwpYMsxjsHgMDAQNBnn9M0zWq1CiFwcodnz56lnbYZQVVVAMAiAfpEEhk8IN6CHEeMH9CbhOdC+RRCJOm3yAh4CxaLRZ5OVdUMHh90/yTpCmEL2VRX8GHQNM1sNnPOFUVBE5BuXcED4ux7OB1niuBzaLVaFUWxWq0oKmlsb/P9JOiKAoLD87YLpLTYhQT9S349qeuKEEKmFeqKpmmvaH5Dq9Uqcx9NJ5bq9Ou9btOlRGHdBS2+XKlpmqqqWMPIrOn1sM4k7wKrTRlMN9D9YKQrhC1kU11BU45V1CTWJH26IvcV+sOc4jb4hKNlyZy6JBcaCA0EB92zJL+msqj2WDTZirJZV5KnvHhlU7Lj6TZu3Fi9enWZiRnRe3n92OSSn7GlkgS0zpl1L1i67t69+/TpU6G7djOoW6QrxEuRTXUF/Q8AsGTJkjZt2hw4cEAkrmOmgTDIDx4Nd+zfv7+zs3N0dLQ8i/FJxs/SYgYGBjo5OeG00EZ5E8lM5wvMARcq8ATfl0g4BIqHksqigrC+9kV5SV0BgG+//ZYZGDJkSGolTSZRkg1eaEmNOwLA2LFjGWMyi2UdP30WWTZQsE0ssz5HjhzyppycnLZu3QoA6O5L4wrTIMld4734+PjgvcjSlUa5Sp6weKnCUG5JVwjbyaa6Ih0F+fPnZ4x9+eWXYPCtG8HnCnsv0WNusVhUVQ0ODr506ZLRaV6vXj3G2I0bN9AkYRKhvcBnW9O02NhY3Njd3Z0xdu/ePfwaHx8/e/bsU6dO4V7SLy/0irPxApLKFQihcbBoYBU7QtaBIoALk9mkCa5xLcmiCk3h9lmEEELjuNiiKw0aNGjZsiXa5S1btjDGRo4ciT+hxZeVA0xnzjn6FXED2auBTk4spbgLNhBxpaoDANOmTUNbjGAXBZYKTHbsQpMtACGE2WzGQ8k2KLrU8F5MJhNjbO3ataC7vAAgV65cwcHBjx49evjw4c8//8wYCw8PB91hJXQrDwaPWXx8vFQpPCwWMDxgXFycvEE8u6Zpd+/e3bx5s0woKRLYCJOTkeOOJpMJE8FsNmOvDwDExMTgZkj37t1JVwgbyaa6gh7trVu3MsY6dOjAGLty5UoSRUFTJat7Ruf45cuXGWMDBw4E3VuCff4PHjwAQw0Rf8JnT1o60P0euDEeMDY2ljHm5eUFBvcL6B280oJwzo1Os4RuFJWDCgAwuecvP7f8DjQAAdbYeHjuGjMsmrBXbiVupvAX6krz5s3btWsnsyMoKKhYsWLSMsr4iIcPH4KhEXnv3r2bN2/K9Ad9FncAuHr1Kqa5THYkLi4OawMzZsyQdXyZiVeuXHn27BnoYoYr7969e/v2bcxQNPq4/s6dO/fv35ciAQBvv/026orsgcudO3dISIg8+8cff9yxY0djwYuOjr527Rp+Rv2Q571///6jR4/wM+dc2v3bt2/L9aijchfsoIqJiZHFyWw2WywW/Ivb/Pvvv3fv3jUmi9CL9MOHDx8/fgykK8TLkB11RVoBDw+PkiVLxsTEMMaGDx8OiZHPWFxcHBoLSWRkJGNs2LBhcg0KFYLhAPhYapqGlWj8i80Xo8DIvfLly9ekSRP5NS4uTiSWFvz67NkzPDLKBIAAkwoAS4dNaFHSbVbX/gAAZgEagCJSXlR7LJpI8NUJEBxQUdKIBwOAVq1aff311zJBfvjhBycnJ5kv+fPnf/r0afHixRljW7ZsAQBs0xQsWJAx9uGHH27fvh10afH19S1SpMhHH31UqFChKlWqYF7gGZs3b54nT5633nqrcuXKv/zyi7G9sn79+k8++eTdd9/NkyePt7c3ZvHgwYPz589fuHDh999///333z9x4gTmzv3792vUqFGwYMGPP/64WLFioNdaGGM5c+ZkjMl7yZMnz++//y7PUqJEiVatWoGuE+3atfviiy/y5cuXM2fOGTNmgC5I165dq1q1auHChT/44IPixYufPn0ar2fFihXFihX77LPPChcuXLNmTVkOhw0b9vbbbwPA2bNn33//fRROZOrUqS4uLvg5JCSkSJEihQsXfu+998qUKWMymTAXJk2a1LVr102bNuH1A+kK8TJkR10RenuFMTZ69GgAKFmyZL58+SAZFy9erFixIlqHjz76CJ/zihUrvvXWW4yx3Llz58mTJ0+ePDt37gSAWbNmMcbQ6g0ZMiRfvnx37twxRuYsX76cMXb8+HEAmDhxYq5cuXB9y5Yt3333XcZYvnz58ufP//bbb69evXr69OlvvfXW9evX8UrwsEuWLPm//8tx+vRpmeYAABxm9B3SpkyNn8rXWdC5Pzwya/ejrQ+jTA8iU1ziH7725UFk/IPImMioZ5GRzyKjoh49BADgHDhPQ1f8/PzatGkDAJGRkTt27Pi///u/Q4cOgS7hjLGPP/546tSp586dM5vNp06dYowtWbIE9x0yZAhj7OrVqwAQHR3dvHlzrHRHRUUVLly4bdu2uNmoUaMYYxEREZqmLVy4ELMVAKxW6927dxljc+fOlap24cIFAPD39z9//jyubNOmjdQhT0/P+vXr4+djx45FRkYqinLx4sVcuXJNnDjx8uXLsgmSM2dOFEIAWLt2LWPs7Nmz+LV169bu7u7oeTt8+DBjbPPmzfjTJ5984uXlhUm0aNGiiRMnAkB4eDhjbN++fQCgqmqxYsWaNWuG23fp0kVeG2NswoQJslS7ubl16NABizdjLCwsDAWjYcOGFStWxG369u1bsGDBjz766MSJE3fu3CFdIV6KbKorePGMMWz+T548mTF26tQpMPhALly4wBj74IMP9u3bd/fu3a5du+bJk+f+/ftHjhz5/fffGWNt27bdvHnz4sWL0RUzfPhwxphxX9QhIcSTJ08AwNnZuWjRomgWhw4dyhjDtsjp06eXLFny3nvvOTs7//333yEhIVevXr127RpjbMSIEQCgKgk+GZeKZT8sVAAAFMUMgkO8FQCW9ezVpXi5SXUaj6xcb7Bb3e5lqwSUdu3h4vpzuSopLkFl7bGUqxJQpWIP10pBNWq0cHEGAOAWABU0VcZFY77g+DsA6Natm7HfvkyZMmjQcTPG2M8//yxtZfHixVu3bg2GQLKCBQt+9913kIxu3bph0BceZMqUKfInY/9Kp06dsHkkwdEzxjVolzETS5UqJUekozDI68SeeXmDBQoUkDf1zjvvyKYwOleNAWMNGzb08/MDXT9wpTCEjTg7O+P0KsitW7fkZh07dpSf+/bt++GHHwKAyWSyWq1ScWvVqoVNJQSdsegqHDRoEGPMGMlC/faE7WRfXXF2dv7888/xmXn8+DFjDA2TdH/5+fkxxqKjo42W5enTp6D7wbCtI8HKr/TLFylSpESJEqA7u+Li4oyuswkTJjDGhD6KDQDefvvt5s2bG21H5cqVP/jgA0jo6RHxoDDGRo4cDgAcuPYsBgBmdekT9IXLdDfvkHotZpRxn+HmNaWa19RqXjPcvKZV8gjOOktljzE1a42pUWdw1RrflHQGABBWAEVw1RimBAZdadiwobHjoX379sZIB8bYypUrQTfijDHcUZpCHx+fOnXqoLkEgG3btvXs2bN///6lSpWqW7euPMiqVavkXqNHj5a2uHTp0thaEnoUn3QxXbx4cfDgwV27dsWINfSqYU2idOnSmzZtAkPgAGNs48aNYOieefvttxcvXgwAS5YsYYxt27YN16PTyc/Pr0GDBo0bN27YsGGOHDk++eQTAAgODsYLkwPg5cHLlCnTvn17X1/fevXqVa1alTF269YtTEZ5L6hY2GBasGDBe++9h+sLFSqEt9m8efNmzZrVr1+fMXbs2DEAGDlyJO4uu3BIVwjbyY66Im2KsU+lcuXK+CDJHtecOXP6+Pjgo4U2RVZXHzx4wBjr1asXfsX1aJWkrmCN7969ezKtGGPojZHPLdpEq9WqqmqePHnQkSJ76efMmcMYO3LkCO6y4Pf5jLF/798BAIwpnvK/oC4la44uUXFdvebb67TYXf/rzV4tN/i2Wu/bKtSr1Y6G3+xokFWWnQ2/We7V7E/fFr9VdO/sVBYAgCsCuIplhz/PGqkrjRs3NnY4AcC7774rq+eMsWnTpoHeLc8Y69u3LxhinKSuAAAa6H79+g0YMKBs2bK4nnMug7WS60rJkiWlrQRD/1bz5s0ZY506derbty9KndQbzrm/vz9j7JNPPpHVheS6ki9fvm3btuGvw4YNk2dEn9iuXbuOHDmyd+/ec+fOHTp0CGMQpk6dmpqutGvX7ty5cwcOHDh16tS+ffsiIiKwYhQQECDLMwAULVp08ODBAFCmTJlRo0bhGXPlyuXj43PlypVjx47t37//5MmTly9fxu2x9AKAxWJB4SRdIWwnG+mKMY5TVsckK1asYIxhNywA3Lx5kzGGDYi4uDgZY4Oxp//88w/TR1TI0QlJdOXSpUuMsTFjxuBXJycnZ2dneTp8boVeF7Zarblz527cuDF+RWfIkydPGGM4DyMAlCtVqsh/PgWAeG4FgN8nT2tbwnVgWa8V9ZtsbdjqL8/mf3k23+bbIrRhi9AGLTbXb7HNu2UWWnxabfNpu73hd+NL1ejyeWkAAK5xAAuAAJ6irrRu3Rr7uoVeFfjPf/7Tp08faa+Nvd+MsZ9++gkM9esCBQqgH6x///7GzrOuXbsa/WBz5syRp5DmGwBq164tOxskR48eZYz9+++/+PXq1auyR81Ijhw5pO1meliBVKZcuXLJfiBVVRljq1evBoCTJ08yxlKcTGjx4sXywoy+qfz583fr1g0/y1TCDdCLKBNk3LhxBQoUwOt58uQJltLy5ctjG90IyqTxAcEDkq4QtpNddCXJCDiMGvrvf//74YcfFixY8L333itSpAhjzN3dHW/nypUr0jMWGxuLD4/ZbMYbv3//PmPs119/ldZBPoq4JVZXXVxcSpUqhQdkjM2cOVM+vb/++qvcWAhhtVrfeuutBg0agN76wZ9q1KiBXounUVGMsTnB0wFAAW7mFgBYPWBs9y+qTavmvs632WaPxts8m29p2GptQ79VPk3CmrRb79tqg2/rLLJs9G29tm6LTQ2+HVemToBTJQAQVlUFULDwGHJH6kqTJk2MXSYjRoyQwq8oCtN76VGDx48fL3vLAGDNmjWMMazsjxs3TprIZ8+eubi41KxZE7+2atXq008/xc8RERE4YhG/hoaGMsbOnTuHX5csWXLp0iUUEnQ0AUC7du2w0alpGrqPkHfeeSc4OBg/58qVa/z48QAQHR2NQRy5cuXCRhJeuZ+fX/HixXHjwoULS18oAERFRaHfD0MWBw0ahOvPnj27fv160KsyUVFRchd5wbK9gkIVHR2NzawyZcqALkILFixgjMkAZQC4du0aFmZMT9wSCyTpCmE72UVXhGH8M7YkOnToEBoa+scff6xevXrlypWrVq2qUaOGNCtRUVHo7Aa9xicM/aXYQdqvXz/QQ4el4cNT4KM+ZcoUxlhkZCT6x43jLpPoisVieeedd9APFh8fL6vA6Bv5999/x48bzxgDq8o1hQO3cgU0DgB/DZvS479fznKrt9L9qyVVvceXcv21RLmRpSqMLl7ht/LuY8rVyiLL2PK1RpavNbGab/8y1b9zqgAAYBUYdsyfz2iWSFfQaqOtf+eddz7++GMZHAUAjLGFCxfiZzSFTZs2ZYyVKlXqo48+YozhGBFVVR89elS8ePEPPvigZMmS7u7utWvXLl26NABwzqOjo3HjDz/8sGTJkhipLE/RvXt3xljhwoWLFCmSI0cOHDP4448/MsYqVqzo5OTUq1cvxhiObvHy8sqbN2/x4sU//fRTLy8vzjkadMzo//73vzhPMyri0qVL5Vkw7guDzS5cuFCoUKEcOXJUqFChRIkSn376qRzpgl33hQoV+uKLL2TfEgC0bNmSMVayZMnPPvusaNGi2CcEAK1bt8Z7kcNC0dMrEw0Las+ePRljJUqUKFasWJEiRdDxCwD9+/eXbjTSFeJlyUa6IvstjCGYRrAfdcGCBfi1Ro0aOXPmNPasREZGYrQMBqHK+iOC7RXcEve6c+cOY2zevHkVKlSoVq2aceMkusI5f/fdd43dCTIuKGfOnN27d3d2dq7nUQcAQNU01aqBxlUrqBzMEDZwUKBzuZEVa/5apuqvrjUnNmwy2sN71leth/s2H+7bIqss9Vv08/Ae7N1oiG/TTu7eAABWARxAA2FwhIFBV27dunX69OmrV6+ePHkyIiICV8rNDhw4gDEUxjmDr1+/vmnTpnXr1smhkTL7du7cuW3btrt372qa9s8//0i7DwDbt2/fsmULavmBAwdw8Dnm47lz58LDww8ePAj6zAsAsHnz5g0bNuBAWmym4PrDhw9v3rwZo37xvPj3yJEjGzduxGhdADh06FBkZCSeAp2rf/31F0YM4nH27dsXGhq6YcMGvEG8HgB48ODB9u3bt23bhoeS13/9+vVVq1bt3r376NGjoLcw7t69KxMNb+3Zs2eHDx/GNVhVwsGSp06d2rlzZ1hY2Llz5+Li4vA2Hzx4gE1DOakB6QphO9lIV3AGDgDIkSNHpUqVpEnCeCG8I6zw4rO3Y8cOjPA5cuTI48ePUQkOHjwo9PhRZ2fnS5cubdiw4eLFi6DHGeNxhD5cGSd3YYz99ddfwtDiwThjofcJA0CpUqVwiMbWrVuPHTsmwwcCAwPxCFu2bgIAbraAolpVs1kxA3CwKgCwvN8vP7qU7+5aa163HhAbB5GR8CQKYuIhxpSFltinEBkFz0zwNBbMGkddURN1sIDhPR9oDeWUz2imsfYtp8NRFEW+aMDYHMTPcsoWmfKy8xxbmcbRrGDwQMr1spaAo9aNOSj02VDwFHIKGdAnVsH1xtBkFBI58B4MnlWcPgASD7A13ohUNaNUxMfHozbIXj3jawXwXMbT4Ylw7hnZjklyeaA3oHFjeQs0Tz5hO9lIV/DR2rBhA2Ns3bp18rERhsn1cLY+rCcCwOrVq5mBSZMmyS3R/47geL0xY8Zgvz3OIoVJtH37dtwmyaOLTjOccRYPePDgwdy5c+PGy5YtA732ioMkEpzdXAAA6FOx4Hh7btEAYOmw8c2cKk34oTsAgEUDm6b8f90IkHNj6nAhRUXqKOjGOslMaBLjmhQ/JF+Z2sZpY7yG5D/JX5McMLU1aXzOyIUlv9/kF5D8stP+KckRAABHCyU5KekKkSLZSFeSv2HFWJ8VhsoghnLKr7GxseimAENVDjFOBcYNMxbjAWWoGOjOLgwBkJsBwLNnz+Lj42W1VF4GXhjoIUPffvstGAKdE555vC+LAgKAw4oRk3s3bw8AoABwEK/+VY8ZWzguxjwC/X2RYIipJewLFlQab0/YTjbSFU1/pxZ+Ng47kNugTpjNZvRj4NSTuJkc6SZnw5XOGflWKE3TUL2E7gcTQsiOfTyjEIJzLqeM5frUlsa5AnElentw8nbs15UnfX7NXAgAa1w8CIBoy8G1m4GDOSZWZN57ol4nsl5MZDVkQLOxXJGuECmSjXSFGyYDtlgs2CGZ5N1NXJ8jVujv3QP9ncHoEMC3cuEoliRKg88Yygm6sEFXEavVii0SHL2vaVpcXBx65DW9zQS6Zx/PK3SNKVWqVN68efGz1WrFy0t4trkQIOIVq1VVQBNgVgEANAEAFg3fTvwa0zczAIC2bdtGRUVduXIlIiLiCpE1uH37Ng4GwoItIV0hUiQb6crLgkKCroC0N0ttjfRNG5GaoenvU0nSfWrk+vXr+fLlw4HlKZyRC6G/qgvdXriXmrQ73GHgnJ88eXLWrFkLiCzDwoULJ02adPr0aSyrxvwiXSFShHQlVfCZ4fqExOkjia4k8bmhaKWhK5JUji6EeP6iXw04AMbuggYghEPqyguTgrAXyZ8F0hUiRUhXUiUr6ApumXzf58dP+Cc4CAW4qgdcgXDI/hWcik2+D43IIshePfluZkQjXSFSgnQlVYzPVboPkrauvNAPJl88bIxbS3R8/aXxQggNdEcYB+CO5wUzplVsbKxm8BMS9kUzDLIxZhnpCpEipCuvnORDBNLexpbtE+0rWy1cjj5IGr/rKLzUjROvkxQzhXSFSBHSFYIg0gnpCpEipCsEQaQT0hUiRdKpK1iYli5devny5dT6BgiCyCbgrJSZa5sIxyU9ugL6TKhr164dPXr0rl27thMEkc0ICwvbuXPnxo0bd+/eXatWLdIVQpLO9goAxMfHx8XF7du3L9zAXoLIBlCZRw4ePLhjx47w8HCcejVzbRPhuKTfD6bpE8LbsfVNEEQWIVPtEuHYpFNXcGosnBjRGBdr7zh7gngdcC644JxrnHNVU9WEkTaJ/5c9EPoUqxQdTkjSqSsSKkzpAwSAJWFCey5AFZDwkisFRzWK5AthV0Boeh6pAhRVMcUJrr8xQTGD0LjVCkJwkZCNQmSjKjzZAcJIRnWFSAc4aBG0BFHRBFjRDOHcXlwA50l1RXPMgY5vCPiGK33mNS6EyQwWCwCc37UndMYcAACTWVgVEELjoOC8n89fkUMQ2QvSFfvAjbNCciE02SgB0JKJCumKveGCg5aQRSA0sFoA4MHfB7pUqvVdiYq7Js4ADqBYQWgaCM6Bcwd8SwFBZBKkK3bg+USRKXeApuQHI12xH1wIwHnYhOCgYcZF7T30c9kaE6s3Gl7Oo3vJKuFT5wAAcJxaGhxwLmmCyDRIV+xAgp0C/lsX/8nfdZr9Tec5bTtNbv3jlJ/8R/+vK2hcCNBUjXQli5CQX5wrFpPQLABw7e+9fWt4DXaqNrOM12rf9lOqNehW0nXf9LkAIBSr+VmMUBRqsBDZFtIVO8AT+lJgUIPGPUtWHlu2zlhn96GlawaVq/Z92coAQLqSpcD8EooFVCsAXNu7r6eHd8CXFRZUb7y2TpsNvt8u92k3qkIdf6fKB4LnAQA8i9EsJtIVIttCumIHpK4M92k4rHS1tZ5t19Zqsdyz9ehq9fq5102kK1rCNPikK3YkIb80KwDcDN//fWW3QTW8x1fxXlP/m1Cfb5Z7t1lcp9lM1/rjKtb76TPnvVNmAwBY4kBQjBSRTSFdsQO6rqjDfOuPLV9zk2frbXXbhDb6ZkyV2r+4e2AnC1c17NyX6kJGyl7IesCpHTsaOLl0Lu/Wp0z1ISWqzKnsvaXxt0vqt1zh02aKs/t459p9nao1+qDoouGjAXhCRBhBZD9IV+wAx/ErAOO+ajvOpfrGul/t8G2+yaPZ2PK1+tT2BjVhCIuqaSoIDgm6IsivYif0/hX499r1S6dOPL7+z4k/VvQpU+WP2o3DPFps9W69wrtFn7Jua4eNfHYl4sbZsxfPnouKiqIh6ES2hXTFDuj99jC2YdvxztU31mu0w6fpZo9mv5V3713bB9SEQRKqpikYXaTpwUj2vvLsCRcCQKgx+ihI4HdPngpwKruoeoPdvl9v9Wy5sGb9bk5l/5oyTcb0aZxEhci+kK7Ygee60qjteJcX6AonXbE3ev8KaFYrVywAcDUsrL9rzeDy7ju9227zar2odqNOX5Q6NG8hqAoIjSuqqqb/3dUE4eiQrtiBxLpSg3Qli4PJrilCaKqqWkCo1w8d7FGm0rzqPlvrtgjzbrOucbtOXzjvmjYdhIa6opCuENkY0hU7IHVlTIPWY0tV2+TdZId3M9KVrAwXHDgIwUGoAOLK3r3dy1SaVdVru0/bbd5tFtdu1K1E2T3BMwEAVAtoXKPx9kQ2hnTFDqSkK9ReyeKgsuCskuJK+N5u5SrNcPPc6ts2zLvNkjpfdStRdjfpCkEIIUhX7ALpigPCNQ4qcBVUAHF5395u5SoFV/PcWp90hSCSQrpiB1LQFZ+mmz2ajS3n3qcO6UrWhHMOikFXupavNL2a19YGbbf5tFlS56tuxZ/rilA514BmCCOyLaQrdsAQZ9xmnHO1DXUbbvdqHObVcpKrZ1BNT9KVLAhP7AeLCN8TUKbidDfPrT5tQr1bLq3zVa8vyx+aORcABLegBNF4exoJrbIAACAASURBVCLbQrpiB563V57rSpMwr5aTXOuRrmRNElQFOEdd2bsnoEzF4Kr1tvm0CfVuuaTOV72/LH9g5lwA4KQrRLaHdMUOkK44HKQrBGE7pCt2gHTF4UhRV6a7eZKuEERySFfsAOmKw0G6QhC2Q7piB0hXHA7ygxGE7ZCu2AHSFYeDdIUgbId0xQ6Qrjgc5AcjCNshXbEDKY1fIV3J0tiiKwdJVwhCCEG6YheoveJwkB+MIGyHdMUOkK44HKQrBGE7pCt2gHTF4aD+FYKwHdIVO0C64nCQrhCE7ZCu2AHSFYeD/GAEYTukK3aAdMXhIF0hCNshXbEDpCsOB/nBCMJ2SFfsAI1fcTho/ApB2A7pih2g9orDQX4wgrAd0hU7QLricJCuEITtkK7YAdIVh4P6VwjCdkhX7ADpisNBukIQtkO6YgdIVxwO8oMRhO2QrtgB0hWHg3SFIGyHdMUOkK44HOQHIwjbIV2xAzR+xeGg8SsEYTukK3aA2isOB/nBCMJ2SFfsAOmKw0G6QhC2Q7piB0hXHA7qXyEI2yFdsQOkKw4H6QpB2A7pih0gXXE4yA9GELZDumIHSFccDtIVgrAd0hU7QLricJAfjCBsh3TFDtD4FYeDxq8QhO2QrtgBaq84HOQHIwjbIV2xA6QrDgfpCkHYDumKHSBdcTiof4UgbId0xQ6QrjgcpCsEYTukK3aAdMXhID8YQdgO6YodIF1xOEhXCMJ2SFfsAOmKw0F+MIKwHdIVO0DjVxwOGr9CELZDumIHqL3icJAfjCBsh3TFDpCuOBykKwRhO6QrdoB0xeGg/hWCsB3SFTtAuuJwkK4QhO2QrtgB0hWHg/xgBGE7pCt2gHTF4SBdIQjbIV2xA6QrDgf5wQjCdkhX7ACNX3E4aPwKQdgO6YodoPaKw0F+MIKwHdIVO0C64nCQrhCE7ZCu2AHSFYeD+lcIwnZIV+wA6YrDQbpCELZDumIHSFccDvKDEYTtkK7YAdIVh4N0hSBsh3TFDpCuOBzkByMI2yFdsQM0fsXhoPErBGE7pCt2gNorDgf5wQjCdkhX7ADpisNBukIQtkO6YgdIVxwO6l8hCNshXbEDpCsOB+kKQdgO6YodIF1xOMgPRhC2Q7piB0hXHA7SFYKwHdIVO0C64nCQH4wgbId0xQ7Q+BWHg8avEITtkK7YAWqvOBzkByMI2yFdsQOkKw4H6QpB2A7pih0gXXE4qH+FIGyHdMUOkK44HKQrBGE7pCt2gHTF4SA/GEHYDumKHSBdcThs05U5pCsEIUhX7ALpisORlh/MB3Wlgt5esXLOQaH8IrIvpCt2gMavOByp60rrUN+mS+o06l28wsHpvwMA5yrnVlDNlF9EtoV0xQ5Qe8XhSN0P1jrUt9mSOg17F69wYIauK8ICqoX8YES2hXTFDpCuOBykKwRhO6QrdoB0xeFI0w9GukIQiSBdsQOkKw4H6QpB2A7pih0gXXE4yA9GELZDuvJa4fryXFdKJdaVWp6gAnDSlayFritacl3Z5NNsKekKQRggXXnlcOMHLsDA2IZtx7lU31i3YZhn421eLSdXqde7ljfwhF+5EAoIDQRw0hU7o+uKwBGPEXt3dytTMdjNcyvGGXs06vWlQVc46QqRrSFdebVwIUAztFFUbnkcHX8vCu7HQKR1SoNWQ78svbaO966vmm6s32S4c6XepavCrTh4rFgfPI179kwBsMgmC+mK3eBcAGjAOXDBAeBieHjH8lUmVfdZ36Dd8sYt5ng16VnC9eD0JQAAHITgwFVB+UVkV0hXXi2oKygtgnMAeHrnfouanvWKl+/kUrOPS/U5bvXCvBr97dN4s0/jieVqjqnq/b8y7k2+qNiocs1zZ88C6UqWQNcVAVwIALgcvq9r2SpT3Xw3+7Zb1bDlwrpNgr50PRKcoCtcCBAqZRaRbSFdebUk6AoXHAQHoSoqaKBFxgS2/LZ/9UYDnGtMLFF5r2/zvfWabK3beG4VrxEV6nZ2823jVu+fwycBQAWhghCCdMW+cCFAcGyvCACI2LOvZ+kqs1x9t3u12+jbcpl7k/6fux6fqusKCMFVe18zQdgN0pVXCMoASoIAwUFwzoVVBQD1ftRor68HOrvPLF97t7ffHs9m27yaL3FvOqBEtbauHs8ibmMXiwCuka7Yn4TqgQoghACAK7vDA52rzKvku7tuu00+Lf90bzKgqOuJyYtRV1QQGqiUW0S2hXTlFZLQp6LrSkJwFxegCgCAe+p4r5a9Pik5t0KNjR4Np5erPrxMzaHVGzw+ewUAQAVuVYALwSkezO48b68IIQDg1v6D3UtXmefWcHNtv/XeLZbWaTLIqfqZOSFSV4QgXSGyL6QrrxCjrnAQynNp4aACmAEexU9q5Nf3y5KzPLx6fVmqj5uH6egFABBWDTQBAtDzQvFg9iahf0Xo/StX9+/vWM51nKvnynp+S32bTq7uFVCswp5J86h/hSAE6corxagrGggFhBmEirrCgSsAVg2eRY9t1KD9fz4d6OMZfewEAFgtFqvVCgDcbAVNgJqgK4J0xU5wwUEAjitSQQDA2QN7mxYvObiqx68ulf0//2JwlRrf/Kfk/vnL9XgwAZpK9QAi20K68gpJ0l6xgrCAUCDhl1ghBACoFrhzbew3Le7v3w0AiikWh69YzRZuVUHVnWAaGSm7kaArynNdufPPxeVjR28aOHTP8LE7R47YOmxE6IgJpzbtwD4x0EhXiGwN6cqrBcdCPv+rrxFcDprTh0HCc0OU8KMcnU8Wyt7whP+E4ILz51mWFM5B49i+pCwjsi2kK68cbvzEDd8554Z1z3/kSTcnC5UV4IasMGZNQgdYkoV0hcjGkK4QRPqR45NIVwhCkh5dSdUJQBDEm0umW5+sAOcc3c7yQ/KfkqxJjjA4tlPcK7VTZ+KNZCleQlcwvQDg999/7969e2BgYGBgYFBQUA+CyMb07J7y8iYRFBQ0cuRIAHgDTKGiKJqmaZrGOVdVFSUTIzBROzVNU1VV9qIpioJbmkym1BQXj2M8oKZpeCIhBH7FY+LxNU3Do9k5LV4ZL6Er8fHxmGQ//PBD5teFCILIwgQGBgJAbGzsqzNGrwdjI0NRFFyD4oGfpSSg9mQw3VQd/Cr0ZgqusVqtdk2MV8VL6IpMmp9//hkAMN1RhAki2yK0lJc3CQDo0aMHWslXZ4xeD7JpkgYxMTEPHz6MiIg4ffr0jh071q9fv3Tp0gULFsydO3deSsyePXvhwoWrV68OCwvbs2fP0aNHr1y5cvv2bYvFkrbkoLC9ebyErsg2XefOnaWu4EqCyLakHA/m8O6i56ARDAgIAACLxWLvy0kEyl7y9aDP5JYaV65c2bx585gxYwIDA3/66Sd/f/+ffvqpc+fOAQEBPXr0GDNmzKRJk+bNm7d06dLQ0NC9e/eeO3fu6tWrF1PhypUrFy9ePHbs2J49e9auXbt8+fI5c+ZMnTp18ODBPXr06Nixo7+/f8eOHbt27RoQEBAQEDBr1qxdu3bdunUrtcsz3qBIpScmxZVZhJfrt8d77tatGwBgjqKu2KkWRRBZAJHK8gYBAF26dIEs0x+gqqqs1KItMn7FWi9+iIuLO3z48IwZMwYMGNClSxfsLgoMDJw5c2Z4ePi9e/de2HZ5FUREROzYsWPcuHEoNv/73//8/f379OmzYsWKixcvJtkYHUV41wjXO3I0A3bOksS8XL893mdyXSEI4k0FH/yuXbtCVtIVtD/C4J8HALPZfPPmzU2bNk2bNi0wMLBfv37jxo1bvXr1v//+m7ah56n3o/BMahZgbw3azBRPpCjK6dOnly5dOnjw4L59+/bu3Ts4OPjw4cNRUVHGe+ScW61WqStZ0w6TrhAEkRZZU1eknX38+PGBAwemTJnSrVu3UaNGzZo1a//+/XFxccmtNvasYBc99nxomma1WhVFSVtyMuWapQZga8N4WCmTSU599+7d1atXT5gwoXfv3iNHjgwJCTl58qQxLE0eMKvZYdIVgnh94BNk76t4OV6/rsi2SBKMInHy5MmZM2cGBQVNmjRp48aNd+7cMVpk3F7aaxnuJQPA0KEkmw5pdOZnoq7IGDNFUbDTXsYiy6sSupdPxt8iqqqeOnUqJCRk9OjRw4cPX7FixdWrVzP9IjML0hXiDSSd3QivDOn6v3TpkhDCYrEoihIfHy9tzWuOq3zZxHydumI2m6WtjI+PR/srDehff/01evTooUOHhoSE3Lx5M+MCIBMkU9Iq3bzwRMY7VRTlxIkTixYt6tGjx5QpU86ePSu1B4UKw5dRLF/L5SeFdIV40+CJ/QmqAe01YjyvrBF369Zt4cKFYOhYTvE6XwXpNsGvWVeEEPHx8RaLRdM0qShXr14dNWrUwIEDw8LCoqOjjfeiZdU+hleEsXgLIR49erRy5crAwMA5c+bExMTI9Sgw8fHxdrlI0pU3mZTntXRQUrmBF94XZAHMZjMKyeDBgx8/fjxr1iwAePbsGeiWmmd4/N0LsTVdE8+izfVr62KjrmS4qOHpMKAZAHbu3NmpU6cZM2YYjaYQwmq1ovHJbrqCbZEkOQsAN2/e/O2337p06SKbcXZMk+yiKzY+YxlEVgNf6VlsvZjU1qeoNlltEQKjdRO+cy7wK8hfU7Zdr8QkZx7Dhw8HgPPnzy9YsMDe16KXT4OKJJaT50UGZHslcYonE5HnWcZTzaIXINsoGzZs+Pbbb8PCwuQFy753aVvRfyjbiC88OCR+Kl/o70qHzzC1vYw/QXqNAxphocccY5OO6x1ImEozZ87s06fPhQsXEuWyvvvr8e+9+boi3bXPnj27ceOGHASLF69m3vhhrJDihwMHDuzfvx/s15/GxfMXgiVZHAPOgQNwEBw0fKsWBxUgTlHRuCW/L0z/zp07DxgwoEePHj1fGYGBgf7+/r179+7bt29AQIAtu/Tt27dfv349e/b08fHB0hgeHv7JJ58MGTKkX79+QUFB3bt37927d69k9O7d++effw4KCgoKCurZs2dQUJCcly/d1x8UFNSyZcvdu3cDANffFoOzMnMQKggrCCuI5+s1AQBdO3UGAKFyzpWERVOEUHEBocXHmzWR8H5tC4BFgKaBptn0ejOpCmhkLl682L9//7///hvTKslzKp8p2x8u6QyUYWBms1kkq/WbzWbULekyxY1xS9wlRaxWq2ySYihaEqMvdBWUqoAHtFqt3DAYxZZ7SUMCpWgBwNy5c4cNG4aXhJchLSHySk3TG64rWPexWq1fffUVMzBq1CgsAZk4P4/UFQDAs6AjOLOO/1Jg3TPFceAqOMCiQcL7TjhwDkLRVKvQYuLjFK7xlCwVCIEmo0+fPi+qptsB+ewMHTpUrjx//vyKFSvscj379+8PDQ0FAEVVgSe8z1QFoYCwgDCDMCVkgf6OGYDOXToDgMY5aAqoKqgqqEqCdGgaaCoA4Ow1AKBwjXNNaJpQNWGDsMTHx6M9UVUV50oBw2jHjNf/ZPqfOHHC399fCCE7bxLKDwCaXVVVjxw5ould36qqWq3We/fuDRs2DNJ8lvH4K1euBF0/rFaryWTCnywWC8Z3oZVYtGjRn3/+ibuYzeaoqKiWLVuKDLRjROI4ZrzfyMjIQYMGbd68OcUyQLqSIQCgfPnyjLH58+fHxMTcv3+/V69eHh4emZ64Rl1ZvHjx77//DmnWcV4tXHBIeXEUngsMCIslIQxUsSochJaSDimKFQD69+8Pr6sPPC4uLkn/fGoIPThn8ODBAHDmzJm///570qRJPXv2BICoqCisUSbv/EdTK11DxuLK0wsA7N69e9WqVQAQHx+f0C7hQgihiedpm7KuCK4IRRGqIlRFKCpouGigqWYrqBwEABegcrkIG3QFb9Bisfz222/YPYCdT6reblAz7FfABAwNDS1dujQ+pzi6EDGGnJUoUQI7b1BpFEW5f//+V199lYbRl7I0YMCAX375BUXFaB5VPaoY079QoUIHDx4EgJ07dwLAvXv3GGN49nTfoFFXMPXwXDt37sT+vCSx1KQr6QcA7t69yxgbMWKEMU3j4uKEPn+1SMkpbzxCaiQ/F2IMPDe2TJPAE3fGpHHk9MCx+skV4AoIuWggQBOgZvlFExqoCqgcVABNs1puX7kCqgomiwCQlWsFhBmEBYQFhCneBPq0u68aRVEiIyNBtyY27gIAQ4YM2bBhQ4cOHbZs2YJPOzazZMwxWlJp7zRNww0URUkys3pGdGXv3r1bt27Fo+kykNivyBN/BejasRMACI2rQlGFioveJFE1oWmaFUBwq/UejqtQVUjwlb0YAIiMjJw8eXJsbKwc9xcTE5PB9opMfBl9t3///nr16iXPHVVVsc0EAM7OzqBPej99+nQAePDgwU8//SQ3TnJw0BsoAPDkyZMBAwYYfwoLC5MZh8f/+++/O3TogL/mzp0b7z1PnjxJjv+yJKmOcM4tFgtqyenTp2fMmJHklklX0g8AnDt3jjGGlQiMvcMrl88tZuSMGTPat2/fqlWr2bNny3oK2oIePXrExsbGxMS0b9++a9eu0dHR06dPnzNnDuiOWtx+x44dQ4YMwSRasGDBzJkzZZlDl+vSpUu///7777//fvXq1cJQxwGAhQsXBgQEfPPNN6NGjYqKisIrzOBcp1YloXpiVRQOhi5UVcvyCxeapoGFcwtoFlAsANDrux/WTJsBAkDVFIuVa1zlmqo7bcyQUDh79+4tC2e6za6iKLdu3Zo7d+7ixYuXLl0aEhKyTGfXrl0AMGPGDKxgCiHQ5Ml9pbsDi5bJZLJYLNLuLFmyJCQkxGKxTJgwASUQd8dfsTwYA37MZjMeljGGLj55nTKjeeJYshfaCwA4cODAunXrcGNTXDwACE2zWiyaoqqKqimqpqhgmJsZAHr36g0AVrMFrFawWMFiBbMVNJ6wcC6EFTQLaOqi4GlTRwwHAG6JU8GaWnMFI4mxXg8Av/76K/qNud5uw4c03bqiadrNmze3bdt26tSpQ4cOnTlz5vLly/3793d3d7958+bBgwcPHDhw8uTJdu3aLVq0CDMLrbCLi4vMC2ym3Lx588cff0TZ2LNnjxBCUZTY2NjLly8fPnz4xIkT+/btO3r06JEjR86dO3f+/PmzZ8/OmTPn4MGDe/fu9fDwGD16NADgoCW0n9ieOHToENql+/fvFypUCLNv3bp1Qg/6yhSwPFy6dAk1EkEH3avjzdcVRVEYY++8887169fx+i0Wi9lslp1pd+7ceeutt/Lmzdu4ceNGjRoxxlxdXWWbIyYmhjF26tSp3Llz58qVizF29OhRHx8f2W6V2vDWW2998cUX+LlWrVq5cuVC+4KH+vLLLxljbm5u9erVY4wVK1ZM7l6iRAnGmLe3d7t27XLmzJkjR46oqCiwuR8vOQnPsVW1xMYpFqswVj+50ISmZvWFa0IT3ARaPCjxYDGBos4M7PVTjTpnl68BAOAgFE2zKPC8n5kLg66ku8DIQv7nn3/mypXLycnpP//5D2OsYMGCX3zxRe7cuX19fQFg7NixWAA0TTOZTNI4apomo4dlDUY+zJphzEp4ePiWLVvws9VqxXEGJpMJt1dVVVY28S9jDJ+7NK75pXRl/fr1AMAFj9cUM9c4JH11sqqocgGAngHdASAu+plQLNyKixk0BVRcrMAtPOYpqOraCZPdPyu6esoUABDx0cmCyBKBVa6JEyfevn1b6qgkI7qC3Rv37t0zmUyRkZHx8fEmkylnzpxNmzY9efIkfsW/2PSUuVOqVCmZmA0aNACAe/fuNWrU6PTp08HBwQ0bNgSDTwJrDDExMRgHIXOtTp06MTEx0r0mdEfo/fv3c+TIgRv7+/uvXr365MmTe/bsyZs378WLF5cvX+7n54ezYb7s/aaGvK958+bduXMn4x5FW3jDdQWzf9myZdiR3rt3b2GY8RQ/Fy5c+NNPP5Ul6datW4wxbMxyzq1WK+47cOBAuc2uXbsYY3PnzpXF8ejRo4yx5cuX4waenp4fffSR3L5+/fqMMRlXLoTo1asXfkaJMro+c+XKVaVKFRttRIpwIUBw0ADSmvfIwZj5g3/XirXaf15u94q1AACxFuAAGM4kBE/cXslgsUliqRljN27cMK6ZNWuWrFhIrFYr5iNWw+V6rMTIrzL2CQz+EzD07aPvK/k1YGfMC6/25XSFa8KqmWPiQH3BAJo5Q0anvYHk0qxlgZU8vitVec3wsQAAMtzYENDM9SvHmCjsdtISj0fJoK7ILivQtXnGjBlVqlTx8/M7c+aM0egj0dHR69atO3r0aLFixcLDw9Fz3qJFiwsXLmzYsKFRo0YAcPz48e7du4MhmlRa7VWrVuEBVVXlnBctWlTmphBCzkI2ffr0AgUKHD16FPRXDwBAVFRUgQIFjBeTie8jwG4kjFPo16+fvMLMOn6KvOG6IjP+yJEjMhhMhgxZLJaIiAjGWHh4uDFTmzZtWqhQIXzmTSYTY6xy5cqgSwj+ZYxVr15d7vLLL78wxqRruHbt2gULFgTdUcYYQ/+snA5P6PLGGJs8ebLx7OPHj0eblW4/GBcCQIhnZuDw6NL1P2fMXzdv8bp5i9bPX7x+3uINk+c5wjJ/1ezgNTOD104P3jAl+ODshb81ajmohvfPZWu2rFx7z9JVAAAxFlABg9xk4cy4rqBN54a4TMbY+fPnhW7yAGDq1KmYRxcvXvT39z937hxuie4L/Hrjxo3hw4c/fvw4wdpeutSrV6958+bh+D5paCIjI5cvXx4YGHjmzBn5WGGfyp07dwYNGrRx40a8hqCgIMiAH8zo6HuuKxqHWBU0WD9lTkePRj19/AK9mv/s6Rfk2XygZ8uB9VoOrNdyoGfLAXX92n5eaYhX6/4ezfvXaiyXvjUa4dKnZsNBPo0H1PT6rVbDfsWrDCnr/msVz++/LLNhyCgAwDinROrCBb5KAAAOHjy4Y8cONHYoBhnXFTwyJrLMNScnpx07dtStWxcAFi9ejMml6nOfgN4HVr58eQB49OjRsWPHXF1dAeDevXs4fOf06dMdO3YEQ3tUVVUUrVWrVt24cQOPsHHjRtnLInT51DTtzJkzZ86cqVChwpEjR27dunXr1i3c9/Lly6grMisz6AczFhJsAmKJwn4ddMxm5Pgv5A3XFQle+V9//YWxYbLvbv78+Yyx2bNnb9myZfv27atWrdq1a1e9evVy5syJOYHtFaxPYaHBItilSxe0LCg/hQsXxgay1BVZATl+/Dg2lYyPPX4+duwY1kPXr1//559/hoSEhIaGtm7dmjF26dKldNtHvR+FA4cn5260/bxCV6fqPUvV7Fi0Qg9nt74lK/d1qpTFlz4lK/VyLvdzqXJ9S5brV7LcgBLlh5d2HVep1mz3+tPcG//vE+eLS1eDChAZDRaLECrXkzRT2ivPU1Lv28C3Yki7PGnSJMbYkCFD8uXL17x5c8YYmhupQ9u3b8dKDEZ5NmvWDCs0devWNdZjBg0axBhr27ZtQEAAY6xGjRqygI0YMQILatGiRRs3bswYwzc2pqgfRlucxo1IpK5oXFPBDABrR47pVdptUPHKkyp5jCrnNrJi9ZEu1UY6Vx/pUn2kS/VRLtXHlnPHz2PLuidffivjPrVUrfFl3EeWdx9Vqc4kV6+pbr4Tq3p1/a/z32NnA4BiscQJbgIhBIZmcPlArVy58vTp06DHUGWWH0w1vKcEAH766aezZ8/u2rWrZs2aADBjxozjx48DAPoeheG9haVLl1ZVFZ1RzZo1A4DHjx9/9913AHDo0CF8W65xCAEAxMfHP336dOrUqXguV1fXBw8eiMR9+9HR0dg5V6ZMmfPnzz98+FD+9PDhQ+lCv3v37rFjxzJiV1OsZ+BnvAtqr2QmsoS1aNFCerGCgoIYYwUKFPjggw/efffd/Pnzv/fee4ULF65cubIwdM/07dsXEuvKP//8wxhbuHAh6E6wTZs2gR7eU6dOHWyvAMCKFSvkiBnj9QDAnDlzGGOFChUqWLDg+zqff/75Rx99hMdJ981yIYRqBQHR5675O7lNcW++oG7rmTUaz6/tt8i9UdZffnf/ammtBstqNVhaq8Hymg1WuDdaXr3+ylpfbfRu+Ydn2xFl6/5YxOX4/KUAABw08/OZw1+PrqAfbOLEiXjSxYsX43AloY9eyp07t2y8Ll++HMN+kOHDh3/22WdYkP766y/pjcHAxcuXLwPA06dPGWMYsgV68wg9MEnsxUvdiMSoKwJMALBx5Nh+pasucm+6vsHXyz2b/+Hr96eX35+eKSwhXi3+TLas9GyxoU6LVZ4tlvm0WOrrt6pB29W+rRbW+WpyVc//fVY5dGQwAJi5ZgahwvO5YfDv0aNHcTANBuVnlh9M6AGfALB69WqsGm7bts3d3R0TwdXVFY27bKHi9WAgMu6I/fa3b99u3749AJw/fx6r/Cmm7ejRo6Ojoy9evIinSJLmMTEx6K744osvTp48efXq1XPnzu3bt+/8+fPh4eH/93//d/369TNnzqxYsWLatGkZevYTnxdX4qmx9pOJQQGpke10JTY2FqUCayLz5s1jjMkufSPo4lRVNYmuYPgjAOTPn9/JyQkAAgMDGWP4K6aS9IMBwN69exljOCDOeD34eDPGNmzYkPzsXJ80Oz1wIQRXuAlAiz5/yd+pwvw6zbc0+n6LV7vNnm1CvVttytpLqHerzV6tdtRt9lfd5jvqNg+r13ynT8utHs221mv6d/22od7fzq/hN7yqT4eyVfcu+RMEdlkkVBpep66AXo2Ijo42liLGGMbeYDnJmzcvdqdhCTx8+DBjLDIy0tiNL3fEyc/HjRuXpP9G+sGMJeRlb0TyXFc0DcAKANuGjxtQym2Zu98W7/Zr6rZc69VqvVeLlJaWa+v5rUu84Jqttf021vVb7eW3xtNvQ51mW71ab/BpFeLbcni5Bt9+6bYvZCMAYNS7exWLYQAAIABJREFUCYQJEi5JVVWTyZTEH5ApuiLdmLt27UKTBQDbt2/HRiEAPHz4sGDBgpgO8rygx4MJIQDAz88PAB48ePDDDz+cO3euffv2I0eOTJ7+mLMPHjwYNGiQr6/v/fv3IXHnmREXF5ejR48af7158+bHH39s3CYT2yvyRIqi/PrrrwBgMpletd1+83XFmL7YjY898/7+/gAQHh7OGNu2bRvoPtMkj27y9orskh04cCBjTNO04sWLo0rJGDNjewUjytq2bYtfjZekaRpjDIfyydhz2fuX/jhjLgSIGIgBsEZdOu9fqtx0N+9tDb/+y6vNZvdmmzyaZv1ls0fTbbW/2lan0VaPRps9Gm7xbrKuju+aOr4bPL8K8/5+Vd32k2s17l65du/mbcGkgHj+Dr7XoyuyfwUNX1xcHGMsIiICr4ExJt33+PXjjz92dXV1dXV1cXGpVKlSgQIFIiMj0a0/ZcqU99577913382bNy9j7NixYwCAbjFjUWSMde7cOUnhfNkbkRj6V1TgKgBsGz7hF+caf9RrE9aoQ6j3N5t8vtnUqM2mhq1x2dwIlzabGrbe4NtiY/1Ey4b6LULrtwjzbrnZt8WG+i22+LQIq+sXVrfZmjqNFlT36vKZ6x/df4UYlVsTJnXBUf34HGGrbt68eej4jYuLyyw/GD5H4eHhU6dOffLkyalTp27dujV//vyqVas+evRo9+7dzZo1w0EIvr6+T58+lYlTpkwZVVWPHz8eFRVVv359ALh58yaq0erVqxVFuXTpUvJnE7vNPD09y5YtKzMoSX6hiXdxcTl58iQYRjLcuHHjk08+Ad0pl4Y/Mx15LRvEEyZMePLkyav2gCFvuK4AQMeOHdElKqlatSpjTL60IG/evPnz5ze6Ox88eHDjxg0c4IL99nLoAG6A5SM+Ph494NJjzvX4kxo1arz//vug11g9PDwYYzt27MDdr127VrFiRSyI5cqVY4xhOZNguEhsbGw6b5sLIYSFx4ASHXP+nP+XpZd6Nl/n3vSvuq32eH+9o4FjLGFftQ5r1GbbV222NmoT1rTdpoYtNzZoGdbsm00+3y2u27qvS42B9ZvB3SegCcE1TX0luoLHlBkkdWXatGkyzhitIWPsypUrcvskuoLTTWr6EG65o7e3d968eW/evPnw4cObN28yxo4cOQIAnTt3lroldN/aq/CDca6B1QIA64aN6/hlpeHlPUaVdh/j4j7GpeaoclVGlK0yomyVkeWqDCtdaVT5qgOKlx7nWgvXJFlGla869MsyY8u6TahQY3r5WnOdq/9Zs1FwRffen5ea0b4HcAANQABo+gBMnnBVMp0x41BrUUhiY2NlZSsdusI5x6EkmFaxsbEAsH79+mrVqoHe0MQzxsTESL9cSEhI+fLlV69ejY8nhpU/ffr07t27MvXQnsheGdkgaNWq1a5du0JDQ11dXW/duiWzCT/geB0AKF68ONYeQDf6//77b/78+XHNy95mimAxMw7a3bJlCzobuT48KFNOlBpvvq6gyyIJOAERcuHCBVzp5eX1448/oqHH8A9pMrp06YJZjgP1uT5TgqurK2OscOHCsgxhKrm5ub311lvyFHgQ3BIDBzDOBAs3DospV65chw4dateujZ8hg/FgggtLHAjx9OTZ7l9WGFGy2iSn6tOda80qU2eKc80pzrWy+uJSc0zZ6mPLVRtbttr4stXGlXGbUq7GRBe3NQ3bzKvbol/pGv1recPDKEx0xWqWVvMV6QqGeMn8leMi0VJYLJYk7ZU//vhD2pRKlSp5enpCYrCezhjDOgToPXn//PMPAKxdu1Z6VvEvY0yGpcrC9hJFIg1dUTUACJu9sFP1ev3rNRpYt8HgOr6DPXwHengN8vAa5OE10MNzZIPG3Su7DfWqP8ynwUAPz0H6T4Oeb+M1zMt3bMMmg6vXHlDWbbxrvZHlavYqU3nB/zpjsLuqqqqmgibAKsAqQJUzUwuhjwfo1q2brJmphjcnpru9gofF28cOhu3bt6NUYN7Jujxqw3vvvYd9ZjK5sJM/CSVKlJCyIcNNf/vtNzmT/40bN/773/+6ubktW7YMLyA2NhadHwBQtmxZzHQ5Yvr69etoQ172HlNDDqhCC3P69OmQkBBZgF+D3X7DdUXok75Nnjy5ffv2HTp0GDVqFOalps82ijc1Z84cPz+/Nm3adOjQISIiQjW8JdTf3x/HMeHYaVnsOOeXLl1q37793r17jXkGAMuWLRszZgwkHsowfvz4b7755ocfftAf6ecTnYaGhn799ddff/31Dz/8cOjQIdDdZRlptCqWeAD4d9+xjhVrdXGqHOBUuVupiv4ulTuXqNS5ROUsvnQqUfn70hW+L12+Y6ny/k4Vun1e5pfSNYaWrjW6Ur3ACtV71/KGh49BcLCYNNWqgYi3JlQ/M1dXsMbHGDMGAQNAcHCw9FOZTCZs1MpGJ2MMZ1tAu4a+1oULF6INOnbsmJxUgzGGnhYAwFCxU6dOyZ/c3d0VRbl27Vr+/Plz586dRjzYC0ldV7hiMoNVjv9JlQVjRr1gC52LS1d1LOna0aXqtE7dAQBUoSqKiWuxFhMIXVR4osGSaNYtFsugQYNQWbEvPYNxxkKI6OhoYwzxxo0bcZoW9EaAIaYrSRLhyoULF37++edOTk5FihQpWrRouXLlihUr1qRJExxjFB8ff+bMmQ0bNuAza4zrAYD169cXLVqUMbZmzRquT5IPAAULFsToDPn4R0RE4DDql7rHNDDGwm3cuHH+/PmQuOOKdCVD4HQFyTtIUR4w3VPrXuOG4HTQbQROxoCVTWMzE/MMnwGZUPi6CHSmiWRvEgXDLB1JMJvNmdG/whXBAQCsWf2tJLawbsCIXm5e3crV6t+gMTx8AiC4ORZAM6lmBfgzS0JeZK6uCN0Hhd5/zF8AmDBhAjOMMeKcM8bOnz+P18AYw4mKLRYLlrRdu3Zh9wlj7IMPPsDuU03Trl+/XqhQIVy/c+fODz/8EC0OAFy/fr1AgQL405UrV37++efvv//emCCZoit4O1aLFUCYzXEgFCEsHOI5mDgoPGHiMBUAevYMAADOrdw4qaS+CFAVcxwIDQC2zJjftET5CR17AACoFtCEBhDPVSsGGWtCgFBAL6hCCH2iAbyYmTNnoh0Ew/DD9LVXpKGX89Vfvnw5ODgYDM8mjmbFTjJ8tOUkmMnthgR15dq1a5GRkcLwJhiht7GSWxU5Cf+BAwc0fdo3tCH379/H6Y1f9h7TAAAiIyNHjRqFtV70K3LD3KaZeK7kvOG6YgT0FjF+lTWIFDfOeO9WGkdI+9SZgHFUc8IgSWHwOtjnlTAvBwgVuAAOnIMiAGByQL9WZWoMa/0/Nc4EAFxRuaoB58AT3ggghAAAjLzKzAvRSb4y+TZG853iQYy/gqFum+SnFHdJQmbpir6B/D++UC3RK7tkwmqaZlifeMGMAJg8YWKvnnromgD5vjD8Z/ybWmrfvXt32LBhMswa9GAZzjmaextvWZrRFFM47X3TWJMkj9I+SPIN5F7GRowtV5UcWW3levgoHio+Pn7RokWjRo2y1yvus5GuZC8SPeyOtwguNKzecoG6MrpHvx+9GsPdhLgdU1y8qqjGaXfFq9GVrEMSbchcXUnYLJXdE+tKyljizThJ2/FjxzRVAwFWs8VqtiQclyc+eurXLnvUd+7cOWDAgE2bNsmXcb3UvWuG9xOnO92yMtIbD4Yg1du3b8+dO3fkyJHolbWXfSZdIbIi+OgnTNjOBQAsDJ757O4jrAJzfZLdhPnBuEPqysvqxGvQldSwRVcUiwJcaEqC/8diMoMATX1p+4BTcMoe9Z07d/bv33/OnDkyLAK7x194nDdeV4Shyauq6tGjR4cPHz5t2jQ5DyHo4Q+vH9IVIivCheEtIEJYzBaL2cIBhACr2cJVDQAUq/L8PZiaECAAIEnnNpEiJ0+eXLNmDWSernDBQYDQOEq+pqhmk1lTtTTaJWkgnVcYHAwAN27cWLp0aa9evRYvXmwcEvDCgyT3gzmQrshu9iTrjbdz6dKlcePG9enTZ+XKlTgPuuyOkrO2v35IV4isiFFXuBAChAag4HvX0TkmWyr6gt6SVatWJXnnfA8DAQEB3TMD/wyQkfMG6HTv3r1begkICPjuu+9eagI6G3QlhRx5nn2253tKYSxGrl69+ttvv3Xp0mXYsGF37twxCgzn3GQymc1m4wtvpJ2VzZeXuZzXAVp/TFj8gDEFxqSQ726R0rh///7Bgwd37959zZo1OM+/EXvfE+kKkSUx6opcowmhCb0Rk8x+gR7aJ2zo9CZAD3G0xdSCTbqSLFMyVVeM/dJ48bNmzfrxxx+///77efPmyZnCjdvHxcXFxcUljyd+mSt6tSQJ9OCG4TuQLKzjwoULU6dO7dmz56+//rphwwbZEQXJyrzd75F0hciKJOpfkX/VhKEPKS7yLZ9J3tdrxBjCn27SCD+1haxwDTKI1sbsgCygK3ImVpw20bhlRETE0KFDsTk4fvz448ePJ3k/NAYB42dub5ubBOO1JeHZs2dbt27t169fr169/P39586d+++//ya5LyEE59z47vOscI/p0RWcWcsYB53x54QgjAjONeBcJLzjFlQOVn3h/Pnrb5+/B1fgKITk4wYy94HB51U1Ou9VDQB4Yod+wlg+LdmSef2oGUle0KdVtXFqW1t1JaUls3SFG6Jy5YhCeXlGWxwSEjJkyJChQ4cGBQWNHj16zZo1ERERt2/flr01qZFGOr/wsp8X3VRI+9QxMTEPHz48ceLE77//PnDgwH79+vXt23fChAl79uxJXofARhhWUOQ7ZpKnlR15OV3BKgPOk0gQBPLo7A2IUgDghaPWHRecnSwNXUw1ZPwlSbWqYRjwIbdM8kEkM99Wq/XYsWPLly+fN2/e2LFjBw0a1K9fv7Fjx/7+++9r1qw5ceLE+fPnb9++/fDhwxc2AVMbQG0jJpMpKirq5s2bERERe/bs2bRp0/z58ydNmhQYGDhkyJCJEyfOmDFj1apVly5dSn4XqaWVcRtbtO21YauucH1eBADw9/dft27dSoLISqyygQwcPmTNqrWrVq35c82aP9es/TNk1dYNW0P/WLt7TdjRJRu/ruDxW4fAq9sPbV20au0ff65Zt2bpmpBVK1euCkm2/BmyzgHZtGmT9FK8SnOUmWA92PhCaETTtCdPnly8ePHw4cMhISFLliwJDg6eMGFC//79+/Tp079//xEjRowZM2bChAnTp0+fM2fOokWLli1btmbNmtDQ0NTKm3H9H3/8sWjRotmzZwcHBw8bNmzo0KHY/hg2bNi4ceNmz569ePHirVu3Hjx48Nq1a48ePUpRhHAewhfeYBJdeQ2paiMv0V7BKawB4N69e0eOHDlGEFmJI0eOHE2TDBbaI0eOHT16/MiR48eOHjtx5Nilwyevn768ccr8bi7uP1fwCihfr1PlujfC9p07eOzo7vADBw+eOPb/7Z1pUFRn1sedL/N9qqam3g+pyiRGoyaThIlx0DEZjVuchMT4Ks5UpgyvUUBZFBFssEFBhGjYUcQFE5cojigiESZqWSg7aREakMiiIEuzaLP1ervvc94Px35y7QbSLI4NfX5FWbcvt5++98o9/z7Lcx6Fovwnq587PymKJxtFRUVKpRKb5j0/SzThcP+D21/zsyvSj+BYPH78uLu7u7W1tbm5uamp6d69ewqFoqSkRPrnNOQfSXl5eUNDw4MHD1pbW9va2jDMOPLHiaJoMpkMBgNfFmUEB0XKVNAVHtYEydxOgnBSBBEATNWNG//8wb63lnztsiRu4artbyxM/WLziz6z58jk0hXech+ebfaFv8V4EfZB4TmnIRMV0nfZc5ekI0g/Czew7x9WQmNJsSAIPP0OlsUUcOnMkZk6ukIQToXkWRVFE9MO6kRBAEEEE3QXlH/xyhuh73145gO3zGXrvl/invz+p+v/5/Xkf2yEAQE0BmBPu2OByHD76c8kxKFs1miRpmFGSD9I909IlmIMI4z2LQ6VU5FCukIQw2J5XEXGmNnERBMwvQkYPC4u/2rOuwcWfRznuuzCok9yPnK/tHztifc/jZ2/cvPMuYfW+0D7EwAwC8LTtphcVCbnY+RoZotwcEhXCGJYJLoCTGSC1ggAXVV1X7r8Jeid+RFvuKa+t+TC4hU5Kz+/tOLz7xauTHhv6Z4/L/Z4aU7s/3roBgYBAHtkka4QTgXpCkEMi9RfMQkMGKgaHvqtdvf/27J97y9Lmrc0+Y2/nnr/bxeWfnR+8cdH5y3ZN8s1bv7Krxet2v7e0viv9wOA1qIupCuE8zC6+SsE4VQ889cPAjz77Sp9w+bQ2XMzFn18ddnaK4vXHF/4qc/rc/uV9/kBjKGfIz7zMwmZaLNDTHFGoSsE4byIohkEYCYwgygCtiNLXb8pZM68c4s/vrp0zZXFa47/9dPNs+a2Ff8EAKJZlK7fThBOBekKQdiBla6YnupKqI2utBf/hCvEkK4QTgvpCkHYgSiaQRCH1ZW1v+hKEfkrhLNDukIQdmCfrvjMfu/RT1Ugkq4QTg3pCkHYgX1xMJ9Zcx/9VEm6Qjg5pCsEYQekKwRhN6QrBGEHT3XFbNEVAIDU9RtD5rx3bpFEVyRxMEa6QjgrpCsEYQciM4MJzAxEEEUAAQDgyP9tDp3jemH5qtwV67I/dE9b4OY10wXrjIGBSLJCOCukKwRhB0Prinfo7L9cWLYqd/m67A/XHlng5vW6S1sR6Qrh7JCuEIQdoK6I7GkcbARdIX+FcHpIVwjCDkRmBpPIntGVNA/v0DnkrxCENaQrBGEHVrpiBmCQvslPNmveheUSXaH8CkGQrhCEXVjFwcwADI5v8g2x0hXyVwiCdIUg7MIqb0+6QhDDQ7pCEHYwgq4sW3V1xbrsD9emLXDznOnSinEwWrOEcGJIVwjCDobSlfRNvrJZ886uWHVl5bqLS9YeWui2YbZLSxnpCuHskK4QhB0M46/IZs3LWL4q56N1WUvWpi1w2/i6y6MS0hXC2SFdIQg7GCZvL5s17+KSVXkr1l1ZvPbYfDevmb/kV4CRsBBOCukKQdjB8HXGWUtWXVu27uqitemubj6vuXQUKADwANIVwkkhXSEIOxh2XqRr5mK368vXXV3sfmzex1umv9NeUA6MdIVwakhXCMIOhu/jcmn5qtzl7tmL1hxf8KnnjHdaC8spDkY4OaQrBGEHQ/ad9PDeNdv17BK38+///YzrylTXv2+c+c6j4nLK2xNODukKQdiByESpv2ICAEj611cBM/6cMu+DxDmuB2bM2z1n/j9emfOwqIR0hXBySFcIwj5EJj4NbYFebxDNptMnT4XvlGWGfH1BFnM+9OszYV8fDo3qutcIAKDR03qRhNNCukIQo0JkjJlMJpPJhH4JmAFE+AWjyPRGZjCRrhBOC+kKQYwOURQBgDGm1+ufagkDYMAYAGPMLIpmEYD6gxHOC+kKMfWRpjpECyMfb3sMDIMAYAIwAeARzGxmJhHMQxw/qhP+1ZMkCIeFdIWYgphMJrPZjKbZbDajTTeZTEwiD2az2WQyGY1GvV7PhpcNKXq9XqvVqtVqlUrV2dnZ2dnZ1dXZ3KNq6Va1dapUnaruDpW6XdXbquprVak6VE+ePNFqtYIg4DmMjCAIKCSCIFhJEZcZs4QXd3cJ4lcgXSGmGmiduSHWarUYudLr9bhhi0ajUalUSqWysLAwJyfn7NmzycnJUVFRcrk8NDQ0ODh4+/btcrk8IiIiJiYmNjY2ISEhPj4+Pj4+ISH+QEJcbHxcfHxcYmxccmzcoQNxqfvjDu+Pi4uNjYmJiYiIkMvlISEhMplMJpMFBwdHR0cfPHgwIyMjNzf39u3bd+/ebWtrU6vVQ56Y2WzW6XSoTIwxqVi+6NtMEMNCukJMNbh4mEwmg8FgZaZVKlVpaenVq1dTUlL27dsnk8mCgoKio6NTUlIyMjJycnKKioru3r3b3Nzc09NjjxMzWtRqdVtbm1KpLC8vP3v27MmTJw8dOpSQkBAYGBgcHBwZGZmcnJydnV1UVNTa2vpLCgcAAKSOy4u+zQQxLKQrxNQBPRUrO15VVZWZmbl3796goCC5XJ6YmJiVlXX79u2Wlpb+/v4RBEA6FI6PNWCiBCaKguTHKIpGUTQw0chEs/i0ckyaKbEa1hatVqtSqQoKCi5fvpySkhIeHh4SEvLNN99cvHixqKjI9gwJwgEhXSEmGYIgGAwGo9FoMBhEURQEQavVWjkEmZmZ0dHRcrk8MDAwLy9PoVD09vaOoB/D8YyEWPY8e4T1K/4z3GgjX92QZ/j48eOSkpLs7OyQkJCdO3eGhYWdOnWqs7PT6iow76LRaDBchvkkgvjvQ7pCTDJ4ma80WcIYy87O3rZtm5+fX3JyskKhePLkiU6nszLQz6XCShzmZ6KGt8kJiaJYVlYWFxe3ceNGLy+vCxcusGcFiVcoUEUZ8UIgXSEmH9zUGo3G06dPb9iwITAwsKSkRGpb8cu70Wic7DVU6OVg6ZogCDqdzqq6rKSkRCaTeXh4JCcnW0X2SFeIFwLpCjGZQHOp0+lyc3P9/f2DgoIqKyul39MFQcBAGe7hG/irF336I2Ebc0OMRiNP0nA11ev1er0ey6n55be0tISFhYWFhR07doy3A3hRl0M4M6QrhIOCZcFWJrWkpCQ8PDwqKur69evSb+W2oIMi3XDk+R9Wwa7h/IyRMzT87XV1dTKZbO/eveXlT5srazQao9GIQuvg+kpMAUhXCAcFv4xjfh4AFApFUFDQ999/z10QjUYzpKLYg8Pqij25/ZHh0yoHBwcvXLgQFhZWWFiIjgvWO5ATQzxvSFcIB0Wn06G1bWxslMlk586d44Edo9FoNBrZs7GjKaAroihiBmWco2FWiQcAf/jhh71797a2tmIMjerEiOcN6QrhuADAiRMn0tPTcXogeirYfwWnoNsD9wCs8g0wDPhbUTLjhO+0OsbqSNuT5weLzzYok25Yhb/4RMgx3zRRFFFXfum4DCAIQmpq6oEDB3iQjbwW4vlBukI4EDzxzhjr6+uTyWSPHj0ap53F0QYGBrq6ugoLCwcGBvr6+np6eviGwWDo7e1Vq9VarTY5ORkAcEIMfuV3cXFpaGhA0wwAbm5uP//8s9lsxpf8SF54Jlo6kj169CgtLU0qh7xRGHpLYJkj+cc//rGpqYlrwLZt29zc3LjSjOd+WmmqWq2WyWQdHR0A0N/fz4YXRYIYD6QrhKOAsSC0wh0dHZGRkUwSIBrzsLyby82bN19++eXu7u76+vr6+vqHDx9WVlbW19c3NDQ0NjY2NDRUVFT8/ve/B8mU+MbGxqCgIG7x6+rqvvzyS/5SpVJx+UGwRou/XLp06eXLl0EyoQQAnjx5gnvwyIaGhj/84Q8AUF1dffToUQAIDQ0NDAwEAI1GM1H3ljGGkUMAiIiIQLXG3NUEfgRBIKQrhGMBAL29vfHx8fgFnzGG/YbHA1rwurq61157jRt9aatHjUaDG6+88gpYmh+jiR8cHAQA/Dc1NXXfvn1FRUUFBQV37tyZNm1abW0tvtFsNg8MDGBiHL0WALh169b9+/eZRVE6Ozt9fX2564OG/rPPPuvu7gaAI0eO7NixAwB27NiBG+N01KxA1wqvKzExUa1WO2BdHDE1IF0hHAi0emlpaQ8fPsS+8eOPBeGMQgCoqqpycXHBxvUAMG3atL6+vr6+PgA4fPjw6tWrAWD27NncX6mrq6uqqkJHx93dHWWmrq4ORzt+/HhISAj3V/r6+u7du6dUKu/cuVNaWlpYWFhTU1NbW1teXl5WVubt7V1SUpKXlxcQEFBdXY2CgX1oli9fji99fX3r6+tNJpOfn5+fn58oijdu3Dhy5AjYZGjGAN5JLLHDSGN0dPT47y1BDAnpCuFAmM3mmpqab7/9ln9VH7/h48mMmpqa6dOnA0BmZqZCofDw8ACA/Px8ANi0aRPOr0R/BQD6+/s3bdpUVlbW3t7+pz/9CQDOnz8/MDDQ0tJy5coVxtjbb7+Nw0oz5Gi+Ozs7UZCQpqamDz74gL/EY9BDksvl06ZNw/1r166tqKhoaGj46quvPDw8WlpasrKysrOzDQYDxvHG47eJNs1gcnNz79y5M4H+EEFwSFcIRwFt34kTJzAxPlHDcl2prq7GOFhDQwO35t3d3ceOHfvnP/+JL998800e9bp48WJ/f/+ePXtu3rwJAPfu3UMVOXjw4IIFC/AYaR97s9mMsw4FQcjMzORBp/j4+KSkJDyGJ1pMJlNHR0dGRgaeSUVFRW5uLh7j7++P+RXu1vCNcd5bDmOss7Pz8OHDpCvE84B0hXAgAGDPnj1arfY56Qr6K4Ig/OY3v+H9gPfs2fPZZ58BgNFofPXVV6X298GDBzk5OdwWA4BOp/Py8lqxYkV6ejo/jLftwoQQACQlJWGEDQBeffVV/Cyj0YgFWqg9Z86cAQDUFZQu1KGdO3disYDUDdLr9eOZJ2+rKwAQGhpKukI8D0hXCAcCAPbv348ZdTZBVbBcV5RK5dtvvw0AV65caWpq+t3vfodGNjg4+KOPPvrxxx8B4KWXXsKdWq1Wp9Ndu3YNAHp6eurr61FmtmzZgvmV5ORkFxeX4OBgpVKJvgv3SACgoaHh1KlTAFBaWvr555+jZ8OLjAGgsrKyra2N60pPT8/jx4/7+vpMJhP2PcMjo6KiKioq+OBjviG2cbD+/v6YmJjxjEkQw0G6QjgQAJCTk3Pr1i1uf7EedzxjSv2Vt956CwAwGT5//vzHjx+XlZVVVVW1tbVhhfGcOXPAMivF3d19zZo1e/fuvX///uDg4NWrV9evX19ZWVlQUJCfn69QKEJDQ8PCwnB2C5aBMca4fnh7ewPAsmXLampquORIrxRBXVEqlTU1NU1NTU1NTVu2bPH09GxtbS2rpquoAAAHm0lEQVQtLa2trW1sbMRQ2Dj7emEeiFnUWqFQ/Pvf/6Z6MOJ5QLpCOBAYIAoLCwNLUxO08uMZU6orb775ZnNzMzaTv3Hjhl6vP3v2LNr3uXPniqI4c+ZMbvF7enr41/yBgQEAcHNz02g07e3tmHXH4jHpqaIAoMvS3Nz87rvvbt++XeolWDkHXFekhISESCfNjN9ZYRJ/RavV4nZkZOTEzo8hXghjbmX0XCFdIRwIURQB4O7duxkZGeiyYGJ8PGNKdWXGjBk6nY5nwn/++WdUMgxtaTQa7q/gHvzorq4uhUIhiqK7uzuuO4m6gsVj2COAiwp+KF7FjBkzEhIS+GwVW4HkuoIpJe7oBAcH48hYi8z7RYoTFAfLzs7GEB/1Np7UiDbhTQeBdIVwIHBlEQA4f/58cXEx2Bi+MRhW0dLIBP0VsHT2FUUR412Dg4PMMnXm5Zdfxgejt7c3JSVl27Zt586d44Gs1atXo0jgvzgagotu8ec8Ly9v8+bNAJCSkrJ48WI+ZwXh5wYSf4XP2w8KCuL+Cp9iycY0P1R6uwAAF9Csra09ffo0XgXFwSY1pCsEYS/4p3nixAmsmAIAXMQerflopYX3L1EoFHx6Ci/cwiezv7+/tLQ0NjbW1dUVD1CpVFiGK+3LsnLlykuXLhUXFxcUFFRUVPz2t78FS5UXWIShrq4uLS2trKwMJDn8hQsXTp8+PTw8PC8vr729HSQqgroiCAL3ewICAri/gnZ/bG6KaJlVyufVA8ClS5dOnDgBlob8pCuTGtIVghgdAFBaWhoZGYnNrPCb+xhy+NyCNzU1hYeHAwCuFWZ75CeffIILYYk2Vbk4SEhIiLQDGFZ8IVqttqur6/r168XFxXyNE5CUgdXW1i5duvSLL74YGBhgFucDLLoivWofH5+IiAg+8phjX8zScxMvR61Wx8TEFBUVgWQlNNKVSQ3pCkGMGgDAHsNYwQVjmhvIHR3UAxwBnrXXgiBg4gQsUx3R7LKh2unz7/4AgO8VRdFoNPb19XHPAHfyEBYG3BBuC3A/fq7ZbMYgFQA0Njbi9vhr4fgaX+np6bt37+Yt0aQLaI5nfOLFQrpCEKOGZxfq6+sDAgJOnjzJ/3CtjhSHWuCESR48zCXwtXit7CnGsqRluIODg5iD4ePwumej0Yh2H3Mq/HxwJw7O/zUYDChUWIjFc/iYk+fVybiIGV4vY4yLHxsxCMbFz3Y/v1GnTp0KCAiQtvrHM+Hr04zmP4RwLEhXCGIU2EaiAKC1tXXr1q27d+/u6urC/YIg4ER0sKzcjtbfSlqGU51fxZ5HSDr+cIOPNpZlNT7fL12sjFe14R4sbOPvGhgYCAoKCgwM5CUDozoBYlJAukIQo8DqgUHXAR0CnCi+YcOGy5cvMxvT//zOYTjGk/+w53OtdEUav0K/hy/lAgCDg4Pl5eW+vr67du3ChV7A0hlzYk+ScARIVwhiFNj6K7wYjNvQ27dv7969Wy6X5+Xl8WUlYXx9f0c4h+F4IbqC94Ef2dLSkpeXFxoaunv3bmxIg2AdHVZUT+xJEo4A6QpBjAKrBwa/mGNvR5BMRUTy8/OTkpK2b9+emJh469YtXMZRypDjD7lthT2P0AixL9v4GFcF+699uAqC3t7eioqKo0eP+vv7JyUl3b59W3q9WLis1+tRgbDYmphikK4QxCgY2wPT1dV17dq1pKQkf3//6Ojo7Oxs6TooHBwckzF8G223NKHN545I/QNpMRgfbYTz58cbDAb0tJilGg3DU7iBJQD4L2OMz/a3oqKiIi8vLzExcevWrd98883ly5ebm5ulBzBast6ZIF0hiFEwtgeGSSz+4OBgaWnpd9995+/vHxISsn///oMHD+bm5vKcvy28LJjZOAdYysWVwOpXQ14C1hZLm7vgPEesAeNvl867tKK9vf3atWunT5+OiYmRyWRyuTwrK6uwsJB3+P/VcyCmNqQrBDEKxvDAYOQHBcB2BLVa3dHRUVBQkJCQ4Ovru3Xr1tDQULlcfujQodzcXKVSyaeP2PNB0pcjxMFAMrF/BERRvH///o0bNw4fPhweHr5r164dO3Z4e3vv37+/qKiotrYW25FxmMXjwTrm/+b/C+FQkK4QxCgYwwMjfQufiQKWOYBMMvEewf2PHj26efPmt99+u2fPHtQbPz8/Hx8fLy+vDRs2hIWFHT9+/Icffrhy5Up+fr5arcaFWOyBMdbW1tbT01NdXZ2fn5+bm5uenr5v377Nmzf7+Ph4e3t7enriB8nl8qNHj/74448PHjzgoTmEtyPjkTEUTpxwg9c4UXUKxKSDdIUgRoc4SthQWfHx5+SVSuV//vOfwsLCM2fOREVFpaam7tixw9PT02tEPD09g4KCIiMjk5KSjh8/npWVlZ+fX19fP0IUTsoIN2TC7zMxeSFdIYjJh5WLM35IGIgJhHSFICYfmGnHqBq2ZsEn2WQH0scMR6P5icTEQrpCEJMPnDeDeoCpDvs9GKlrMs6O9wQxJKQrBDHpscrijCHfQxATCOkKQRAEMZGQrhAEQRATCekKQRAEMZGQrhAEQRATCekKQRAEMZGQrhAEQRATCekKQRAEMZE4rK78P61V977dtBCrAAAAAElFTkSuQmCC" alt="" />

android断点续传基本的UI编写

明白了上述的实现流程,现在我们开始一个android项目,开始断点续传代码的编写,项目结构如下:

aaarticlea/png;base64,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" alt="" />

运行的截图如下:

aaarticlea/png;base64,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FwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKXoBQIpeAJCiFwCk6AUAKfde/C9JWS9wmGFTkgAAAABJRU5ErkJggg==" alt="" />

一、 编写基本的UI,三个TextView,分别显示文件名、下载进度和下载速度,一个ProgressBar。二个Button,分别用于开始下载、暂停下载和取消下载。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.linux.continuedownload.MainActivity"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> <TextView
android:layout_marginLeft="80dp"
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> <TextView
android:layout_marginLeft="80dp"
android:id="@+id/speed"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<ProgressBar
android:visibility="invisible"
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" /> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"> <Button
android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始下载" /> <Button
android:layout_marginLeft="20dp"
android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暂停下载" /> <Button
android:layout_marginLeft="20dp"
android:id="@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消下载" />
</LinearLayout> </LinearLayout>

二、 在MainActivity中初始化一些组件,绑定按钮的事件:

在onCreate方法中初始化一些组件:

// 初始化组件
textView = (TextView) findViewById(R.id.textView);
progressView = (TextView) findViewById(R.id.progress);
speedView = (TextView) findViewById(R.id.speed);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
progressBar.setMax(100);
startButton = (Button) findViewById(R.id.start);
stopButton = (Button) findViewById(R.id.stop);
cancelButton = (Button) findViewById(R.id.cancel);
// 创建一个文件信息对象
final FileInfo fileInfo = new FileInfo(0, fileUrl, "huhx.apk", 0, 0);

在onCreate方法中绑定开始下载按钮事件:点击start按钮,设置进度条可见,并且设置start的Action,启动服务。

startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
textView.setText(fileInfo.getFileName());
progressBar.setVisibility(View.VISIBLE);
// 通过Intent传递参数给service
Intent intent = new Intent(MainActivity.this, DownloadService.class);
intent.setAction(DownloadService.ACTION_START);
intent.putExtra("fileInfo", fileInfo);
startService(intent);
}
});

在onCreate方法中绑定暂停下载按钮事件:点击stop按钮,设置stop的Action,启动服务。

stopButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 通过Intent传递参数给service
Intent intent = new Intent(MainActivity.this, DownloadService.class);
intent.setAction(DownloadService.ACTION_STOP);
intent.putExtra("fileInfo", fileInfo);
startService(intent);
}
});

在onCreate方法中绑定取消下载按钮事件:点击cancel按钮,设置cancel的Action,启动服务,之后更新UI。

cancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 通过Intent传递参数给service
Intent intent = new Intent(MainActivity.this, DownloadService.class);
intent.setAction(DownloadService.ACTION_CANCEL);
intent.putExtra("fileInfo", fileInfo);
startService(intent); // 更新textView和progressBar的显示UI
textView.setText("");
progressBar.setVisibility(View.INVISIBLE);
progressView.setText("");
speedView.setText("");
}
});

注册广播,用于Service向Activity传递一些下载进度信息:

// 静态注册广播
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(DownloadService.ACTION_UPDATE);
registerReceiver(broadcastReceiver, intentFilter); /**
* 更新UI
*/
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (DownloadService.ACTION_UPDATE.equals(intent.getAction())) {
int finished = intent.getIntExtra("finished", 0);
int speed = intent.getIntExtra("speed", 0); Log.i("Main", finished + "");
progressBar.setProgress(finished);
progressView.setText(finished + "%");
speedView.setText(speed + "KB/s");
}
}
};

三、 在AndroidManifest.xm文件中声明权限,定义服务

<service android:name="com.huhx.services.DownloadService" android:exported="true" />

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

android断点续传的工具类

二、 我们定义一些实体类,用于断点续传过程的信息的良好封装:

下载文件信息: 省略了get和set方法,以及toString和构造方法

public class FileInfo implements Serializable{
// 文件Id,用于标识文件
private int fileId;
// 文件的下载地址
private String url;
// 文件的名称
private String fileName;
// 文件的长度,也就是大小
private int length;
// 文件已经的下载量
private int finished; }

下载资源的线程信息:省略同上

public class ThreadInfo {
// 线程ID
private int threadId;
// 下载资源的地址
private String url;
//下载资源的开始处
private int start;
//下载资源的结束处
private int end;
//资源已经的下载量
private int finished;
}

三、 我们开始数据库方面的编写,它用于存储更新线程的下载的进度信息

首先我们要创建一个数据库的工具类:

package com.huhx.util;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; /**
* Created by huhx on 2016/4/9.
*/
public class SqliteDBHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "download.db";
private static final int version = 1; private static final String CREATE_THREADINFO = "create table thread_info(_id integer primary key autoincrement, " +
"thread_id integer, url text, start integer, end integer, finished integer)";
private static final String DROP_THREADINFO = "drop table if exists thread_info"; public SqliteDBHelper(Context context) {
super(context, DB_NAME, null, version);
} @Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_THREADINFO);
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(DROP_THREADINFO);
db.execSQL(CREATE_THREADINFO);
}
}

定义一个Dao接口,用于数据库对线程信息的CRUD操作:

/**
* Created by Linux on 2016/4/9.
*/
public interface ThreadDao {
// 插入线程信息
public void insertThread(ThreadInfo threadInfo); // 删除线程信息
public void deleteThread(String url, int threadId); // 删除所有关于这个url的线程
public void deleteThread(String url); // 更新线程信息
public void updateThread(String url, int threadId, int finished); // 查询线程信息
public List<ThreadInfo> queryThread(String url); // 线程信息是否存在
public boolean isThreadInfoExist(String url, int threadId);
}

具体实现上述Dao的Impl类:

package com.huhx.util;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import com.huhx.model.ThreadInfo; import java.util.ArrayList;
import java.util.List; /**
* Created by huhx on 2016/4/9.
*/
public class ThreadDaoImpl implements ThreadDao { private SqliteDBHelper sqliteDBHelper; public ThreadDaoImpl(Context context) {
sqliteDBHelper = new SqliteDBHelper(context);
} @Override
public void insertThread(ThreadInfo threadInfo) {
SQLiteDatabase database = sqliteDBHelper.getWritableDatabase();
Object[] objects = new Object[]{
threadInfo.getThreadId(), threadInfo.getUrl(), threadInfo.getStart(), threadInfo.getEnd(), threadInfo.getFinished()
};
database.execSQL("insert into thread_info(thread_id, url, start, end, finished) values(?,?,?,?,?)", objects);
database.close(); } @Override
public void deleteThread(String url, int threadId) {
SQLiteDatabase database = sqliteDBHelper.getWritableDatabase();
Object[] objects = new Object[]{
url, threadId
};
database.execSQL("delete from thread_info where url = ? and thread_id = ?", objects);
database.close();
} @Override
public void deleteThread(String url) {
SQLiteDatabase database = sqliteDBHelper.getWritableDatabase();
Object[] objects = new Object[]{
url
};
database.execSQL("delete from thread_info where url = ?", objects);
database.close();
} @Override
public void updateThread(String url, int threadId, int finished) {
SQLiteDatabase database = sqliteDBHelper.getWritableDatabase();
Object[] objects = new Object[]{
finished, url, threadId
};
database.execSQL("update thread_info set finished = ? where url = ? and thread_id = ?", objects);
database.close();
} @Override
public List<ThreadInfo> queryThread(String url) {
SQLiteDatabase database = sqliteDBHelper.getWritableDatabase();
List<ThreadInfo> threadInfos = new ArrayList<>();
Cursor cursor = database.rawQuery("select * from thread_info where url = ?", new String[]{url});
while (cursor.moveToNext()) {
ThreadInfo threadInfo = new ThreadInfo();
threadInfo.setThreadId(cursor.getInt(cursor.getColumnIndex("thread_id")));
threadInfo.setUrl(cursor.getString(cursor.getColumnIndex("url")));
threadInfo.setStart(cursor.getInt(cursor.getColumnIndex("start")));
threadInfo.setEnd(cursor.getInt(cursor.getColumnIndex("end")));
threadInfo.setFinished(cursor.getInt(cursor.getColumnIndex("finished"))); threadInfos.add(threadInfo);
}
cursor.close();
database.close();
return threadInfos;
} @Override
public boolean isThreadInfoExist(String url, int threadId) {
SQLiteDatabase database = sqliteDBHelper.getWritableDatabase();
Cursor cursor = database.rawQuery("select * from thread_info where url = ? and thread_id = ?", new String[]{url, threadId+""}); boolean isExist = cursor.moveToNext();
cursor.close();
database.close();
return isExist;
}
}

下载暂停取消的具体流程

四、 最后我们开始最重要的Service以及核心的下载代码的编写,我们按照上述的开始、暂停、取消的顺序,来讲解断点续传的实现过程。

我们在DownloadService中onStartCommand方法中接收的Intent,关于Service的使用请参见:android基础---->service的生命周期

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// 获得Activity传过来的参数
if (ACTION_START.equals(intent.getAction())) {
FileInfo fileInfo = (FileInfo) intent.getSerializableExtra("fileInfo");
// 启动初始化线程
new InitThread(fileInfo).start();
} else if (ACTION_STOP.equals(intent.getAction())) {
FileInfo fileInfo = (FileInfo) intent.getSerializableExtra("fileInfo");
if (downloadTask != null) {
downloadTask.isPause = true;
}
} else if (ACTION_CANCEL.equals(intent.getAction())) {
FileInfo fileInfo = (FileInfo) intent.getSerializableExtra("fileInfo");
if (downloadTask != null) {
downloadTask.isPause = true;
}
// 删除本地文件
File file = new File(DOWNLOAD_PATH, fileInfo.getFileName());
if (file.exists()) {
file.delete();
}
handler.obtainMessage(DOWNLOAD_CANCEL, fileInfo).sendToTarget();
}
return super.onStartCommand(intent, flags, startId);
}

五、 文件的开始下载流程:

开始下载时,启动一个初始化线程,并把文件信息传递给线程,该线程通过Http请求得到文件的长度,在本地创建下载文件的载体,设置大小并发送下载的消息给Handler:

/**
* 初始化子线程
*/
class InitThread extends Thread {
private FileInfo fileInfo = null; public InitThread(FileInfo fileInfo) {
this.fileInfo = fileInfo;
} @Override
public void run() {
// 连接网络文件
HttpURLConnection connection = null;
RandomAccessFile randomAccessFile = null;
try {
URL url = new URL(fileInfo.getUrl());
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(3000);
connection.setRequestMethod("GET"); connection.connect(); int length = -1;
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
// 获取文件的长度
length = connection.getContentLength();
}
if (length <= 0) {
return;
}
// 在本地创建文件
File dir = new File(DOWNLOAD_PATH);
if (dir.exists()) {
dir.mkdir();
}
File file = new File(dir, fileInfo.getFileName());
// 设置文件长度
randomAccessFile = new RandomAccessFile(file, "rwd");
randomAccessFile.setLength(length); fileInfo.setLength(length);
handler.obtainMessage(DOWNLOAD_MESSAGE, fileInfo).sendToTarget();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
randomAccessFile.close();
connection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

handler接收消息,并加以处理:注意这里有两种消息,我们暂时只考虑DOWNLOAD_MESSAGE消息,它启动下载任务

private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case DOWNLOAD_MESSAGE:
FileInfo fileInfo = (FileInfo) msg.obj;
// 启动下载任务
downloadTask = new DownloadTask(DownloadService.this, fileInfo);
downloadTask.download();
break;
case DOWNLOAD_CANCEL:
FileInfo fileCancelInfo = (FileInfo) msg.obj;
downloadTask = new DownloadTask(DownloadService.this);
downloadTask.cancelDownload(fileCancelInfo);
break;
}
}
};

在download方法中,首先判断是否有线程下载过文件,如果没有就创建一个。有的话,从数据库直接得到。而且开启了下载的任务线程

public void download() {
// 读取数据库的线程信息
List<ThreadInfo> threadInfos = threadDao.queryThread(fileInfo.getUrl());
ThreadInfo threadInfo = null;
if (threadInfos.size() == 0) {
threadInfo = new ThreadInfo(0, fileInfo.getUrl(), 0, fileInfo.getLength(), 0);
} else {
threadInfo = threadInfos.get(0);
}
new DownloadThread(threadInfo).start();
}

在下载的线程中,通过Http请求数据并通过字节流的方式存储在本地的文件中。间隔500毫秒,就发送一次更新UI的广播。如果收到了暂停的信号,就暂停下载。在下载完成之后,删除数据库中的线程信息

class DownloadThread extends Thread {
private ThreadInfo threadInfo = null; public DownloadThread(ThreadInfo threadInfo) {
this.threadInfo = threadInfo;
} @Override
public void run() {
// 向数据库插入线程信息
if (!threadDao.isThreadInfoExist(threadInfo.getUrl(), threadInfo.getThreadId())) {
threadDao.insertThread(threadInfo);
}
HttpURLConnection connection = null;
RandomAccessFile randomAccessFile = null;
InputStream inputStream = null;
try {
URL url = new URL(threadInfo.getUrl());
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setRequestMethod("GET"); int start = threadInfo.getStart() + threadInfo.getFinished();
connection.setRequestProperty("Range", "bytes=" + start + "-" + threadInfo.getEnd()); File file = new File(DownloadService.DOWNLOAD_PATH, fileInfo.getFileName());
randomAccessFile = new RandomAccessFile(file, "rwd");
randomAccessFile.seek(start);
Intent intent = new Intent(DownloadService.ACTION_UPDATE); // 开始下载
finished += threadInfo.getFinished();
if (connection.getResponseCode() == HttpURLConnection.HTTP_PARTIAL) {
inputStream = connection.getInputStream();
byte[] buffer = new byte[4 * 1024];
int len = -1;
long time = System.currentTimeMillis();
long time1;
while ((len = inputStream.read(buffer)) != -1) {
randomAccessFile.write(buffer, 0, len);
finished += len;
if ((time1 = System.currentTimeMillis() - time) > 500) {
time = System.currentTimeMillis();
intent.putExtra("finished", finished * 100 / fileInfo.getLength());
intent.putExtra("speed", (int) (len / time1));
context.sendBroadcast(intent);
}
if (isPause) {
threadDao.updateThread(threadInfo.getUrl(), threadInfo.getThreadId(), finished);
return;
}
}
// 删除线程信息,再次发送广播避免上面的广播延迟
intent.putExtra("finished", finished * 100 / fileInfo.getLength());
context.sendBroadcast(intent);
threadDao.deleteThread(threadInfo.getUrl(), threadInfo.getThreadId());
Log.i("Main", "finished: " + finished + ", and file length: " + fileInfo.getLength());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
connection.disconnect();
randomAccessFile.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

六、 文件的暂停下载流程:如果下载任务在启动,那么设置isPause为true,在上述的讲解中我们知道,此时字节流停止的传输。

if (downloadTask != null) {
downloadTask.isPause = true;
}

七、 文件的取消下载流程:

暂停下载的流程,然后删除本地文件,最后发送取消下载的消息:

FileInfo fileInfo = (FileInfo) intent.getSerializableExtra("fileInfo");
if (downloadTask != null) {
downloadTask.isPause = true;
}
// 删除本地文件
File file = new File(DOWNLOAD_PATH, fileInfo.getFileName());
if (file.exists()) {
file.delete();
}
handler.obtainMessage(DOWNLOAD_CANCEL, fileInfo).sendToTarget();

handler处理取消下载的消息:调用DownloadTask的cancelDownload方法,并把文件信息传入

case DOWNLOAD_CANCEL:
FileInfo fileCancelInfo = (FileInfo) msg.obj;
downloadTask = new DownloadTask(DownloadService.this);
downloadTask.cancelDownload(fileCancelInfo);
break;

在cancelDownload方法中删除数据库中的线程信息:

// 取消下载任务
public void cancelDownload(FileInfo fileInfo) {
threadDao.deleteThread(fileInfo.getUrl());
}

最后在MainActivity中更新UI:

// 更新textView和progressBar的显示UI
textView.setText("");
progressBar.setVisibility(View.INVISIBLE);
progressView.setText("");
speedView.setText("");

友情链接

关于android中多线程的下载,请参见我的博客: android程序---->android多线程下载(二)

上一篇:『Numpy学习指南』Matplotlib绘图


下一篇:分析你的第一个Android程序