【问题标题】:CopyAssets with AsyncTaks to sdcard only once AndroidCopyAssets with AsyncTaks to sdcard only once Android
【发布时间】:2014-05-25 23:51:23
【问题描述】:

我希望我的应用仅在第一次打开时才将文件复制到 SD 卡中,而不是每次打开应用时。

有人可以帮助完成代码,以便它只复制不存在的资产吗?

我复制资产的代码部分位于: 私有类 Asyntasking 扩展 AsyncTask

这是我的代码:

public class SplashScreen extends Activity {

 private ProgressBar progressBar;
 private int progressStatus = 0;
 private TextView textView;
 private Handler handler = new Handler();
public static final String TAG = "SplashScreen";
    String now_playing, earned;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);

    new Asyntasking().execute();

    progressBar = (ProgressBar) findViewById(R.id.progressBar1);
    textView = (TextView) findViewById(R.id.textView1);
    // Start long running operation in a background thread
    new Thread(new Runnable() {
       public void run() {
          while (progressStatus < 100) {
             progressStatus += 1;

      handler.post(new Runnable() {
      public void run() {
         progressBar.setProgress(progressStatus);
         textView.setText(progressStatus+"/"+progressBar.getMax());
      }
          });
          try {
           Thread.sleep(350);
          } catch (InterruptedException e) {
             e.printStackTrace();
          }
       }
    }
    }).start();
   }   

private class Asyntasking extends AsyncTask<Void,Void,Void>
{
    private void copyAssets(String path)
    {
        String[] files = null;

        try
        {
            files = getAssets().list(path);
        } catch (IOException e)
        {
            e.printStackTrace();
        }

        if (files.length == 0)
            copyFile(path);
        else
        {
            File dir = new File(getExternalFilesDir(null), path);

            if (!dir.exists())
                dir.mkdir();

            for (int i = 0; i < files.length; i++)
            {
                copyAssets(path + "/" + files[i]);
            }
        }
    }

    private void copyFile(String filename)
    {
        InputStream in = null;

        File file;
        OutputStream out = null;

        try
        {
            in = getAssets().open(filename);
        } catch (IOException e)
        {
            Log.e(TAG, "ERROR WITH in = getAssets().open: " + filename);
            e.printStackTrace();
        }

        file = new File(getExternalFilesDir(null), filename);

        try
        {
            out = new FileOutputStream(file);
        } catch (FileNotFoundException e)
        {
            Log.e(TAG, "ERROR WITH out = new FileOutputStream(file);");
            e.printStackTrace();
        }

        byte[] data;

        try
        {
            data = new byte[in.available()];

            in.read(data);
            out.write(data);

            in.close();
            out.close();
        } catch (IOException e1)
        {
            e1.printStackTrace();
        }}
    @Override
    protected Void doInBackground(Void... params) {
        // TODO Auto-generated method stub
        copyAssets("ErgonomicsHelp");
                return null;
    }


@Override
protected void onPostExecute(Void result) {
    super.onPostExecute(result);
    Intent i = new Intent(SplashScreen.this, MainActivity.class);
    i.putExtra("now_playing", now_playing);
    i.putExtra("earned", earned);
    startActivity(i);

    // close this activity
    finish();
}}
}

它工作正常,我只想让它发生一次,但不知道如何改变它。 谢谢, 德里克

【问题讨论】:

  • 您应该将状态保存在 SharedPreferences 中。
  • 有很多东西可以破坏复制线程。因此,在您的资产中也包括一个带有文件校验和的文件列表。这样您就可以删除不完整的文件,并在下次启动时继续正确复制。

标签: android performance android-asynctask


【解决方案1】:

我假设您希望 AsyncTask 运行一次。您必须将状态保存在某处,但最简单的是在 SharedPreference 中。你会做这样的事情:

    private static final String ASYNC_TASK_HAS_RUN = "asynctask_has_run";

    SharedPreferences prefs = getSharedPreferences(FILE_NAME, MODE_PRIVATE);
    if(prefs.getBoolean(ASYNC_TASK_HAS_RUN, false)){
        new Asyntasking().execute();
        prefs.setBoolean(ASYNC_TASK_HAS_RUN, true);
    }

另外,我注意到您正在创建一个线程来将结果发布到进度。 AsyncTasks 已经有一个在主线程上运行的 onProgress 方法,所以你可以利用它。

【讨论】:

    【解决方案2】:

    一种简单的方法是检查文件是否已存在于文件系统中(使用 File.exists),如果存在则不复制。一种更好的方法是检查文件的时间戳,因此如果您更新应用程序,您可以复制更新的数据文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-02
      • 2022-12-26
      • 1970-01-01
      • 2022-12-02
      • 1970-01-01
      • 1970-01-01
      • 2022-12-02
      相关资源
      最近更新 更多