0

タイトルからわかるように、必要になるたびに runOnUiThread を使用しないようにしています。どういう意味かは後で説明しますが、最初に、現在のコード (の一部) を次に示します。

private void filePaste()
{
  final File src = new File(FileClip); //Source file (as a string)
  final File dest = new File(myPath.getText()+"/"+src.getName()); //Destination file
  final ProgressDialog dlg = new ProgressDialog(AppContext);

  final Thread copythread = new Thread(new Runnable() {
    public void run() {
      if(FileClip==null)
        Main.this.runOnUiThread(new Runnable() {
          public void run(){
            toast(getString(R.string.msg_EmptyClip));
          }
        });
      else
      {
        if(src.canRead()){
          if(!src.isDirectory())
          {
            try{
              BufferedInputStream in = new BufferedInputStream(new FileInputStream(src), 8192);
              BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(dest));

              long pos = 0;
              long read = 8192;
              byte[] data = new byte[(int)read];

              while(pos<src.length()){
                int bytes = in.read(data, 0, (int)read);
                if(bytes>-1) {
                  out.write(data,0,bytes);
                  in.skip(read);
                  in.mark((int)pos+bytes);
                  in.reset();
                  dlg.incrementProgressBy(bytes);
                  pos+=bytes;
                }
              }

              Main.this.runOnUiThread(new Runnable() {
                public void run(){
                  dlg.dismiss();
                }
              });
              in.close();
              out.close();
            }catch(final Exception e)
            {
              Main.this.runOnUiThread(new Runnable() {
                public void run(){
                  alert("filePaste():\n"+e);
                }
              });
            }

            if(Moving==true) {
              boolean q = src.delete();

              if(q==true)
                Main.this.runOnUiThread(new Runnable() {
                  public void run(){
                    toast(getString(R.string.msg_MoveOK,src.getName()));
                  }
                });
              else
                Main.this.runOnUiThread(new Runnable() {
                  public void run(){
                    toast(getString(R.string.msg_MoveNO,src.getName()),1);
                  }
                });

              Moving = false;
            }
            else {
              Main.this.runOnUiThread(new Runnable() {
                public void run(){
                  toast(getString(R.string.msg_CopyOK,src.getName()));
                }
              });
            }
          }
        }
        else
          Main.this.runOnUiThread(new Runnable() {
            public void run(){
              toast(getString(R.string.msg_CopyNO,src.getName()));
            }
          });
        FileClip = null;
        Main.this.runOnUiThread(new Runnable() {
          public void run(){
            getDir(myPath.getText().toString());
          }
        });
      }
    }
  });

  dlg.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
  dlg.setTitle(Moving?getString(R.string.moving):getString(R.string.copying));
  dlg.setMessage(src.getName());
  dlg.setCancelable(true);
  dlg.setButton(DialogInterface.BUTTON_NEGATIVE, getString(android.R.string.cancel), new DialogInterface.OnClickListener()
  {
    @Override
    public void onClick(DialogInterface dialog, int which) {
      dlg.cancel();
    }
  });
  dlg.setOnCancelListener(new DialogInterface.OnCancelListener()
  {
    @Override
    public void onCancel(DialogInterface dialog) {
      copythread.interrupt();
      if(dest.exists())
        dest.delete();
    }
  });
  dlg.setMax((int)src.length());
  dlg.show();

  copythread.start();
}

このコードが行うことは、指定されたファイル (FileClip に文字列として格納されている) をコピーしようとすることです。

ご覧のとおり、runOnUiThread を過度に使用しているため、コードは非常に長くなります。すべてを移動する方法を知りたい

Main.this.runOnUiThread(new Thread(new Runnable()
  public void run()
  {
    //Simple stuff for 6 lines
  }
));

クラスか何かに。考えていた

public class runAtUI implements Runnable

しかし、私はその時点で停止します。コンストラクターの作成方法がわかりません。これで私が何を意味するかを理解していただければ幸いです。何かのようなもの:

new runAtUI()
{
  //This makes less lines IMO, and could be executed
}

*注: これに関するトピックを探しましたが、すべて同じで、runOnUiThread を使用してください。私はそれが大丈夫であることを知っていますが、短いもの(同じ目的で toast() を使用してトーストを表示する、またはアラートを再度表示するが、alert() を使用するなど)は無意味です。

PS: これは私が行っている単純なファイル マネージャー用であり、資金不足のため Google Play には公開されません。また、広告も使用したくありません (名前の「単純さ」を破ります)。はい、無料で広告なし (その言葉はありますか?) より優れたアプリがあることは知っていますが、n_n の作成方法を学びたかったのです。

情報、アイデア、またはガイドをいただければ幸いです。


編集#2:迅速に回答してくれたすべての人に感謝します!あなたが提供したサンプルは今のところ機能しますが、もっと柔軟にしたいと思います。eval("code as string")JavaScript のように (コードが文字列でない場合)。この質問は回答済みと考えますが、人々がさらにアイデアを提供できるように開いたままにします;D


編集 #3: わかりました、最初に、長い間返信がなくて申し訳ありません。次に、現在のコードへのリンクを、現在の 123 行 (このコード) からpastebinの 77 行に追加します。uithreadのコードも追加しています。アプリについて: テスト用に必要な場合は、現在の状態などを確認してください。メールを送ってください。お送りします ;)

4

3 に答える 3

1

ユーティリティ クラスを作成して、UI スレッドによって実行されるランナブルを作成する手順をカプセル化し、Toast を呼び出すことができます。簡単な実装を次に示します。

public abstract class ToastUtils {
      /**
       * Displays a toast message, making sure that the toast is always invoked from the main (ui) thread.
       * @param act Calling Activity
       * @param text Toast text
       * @param duration Toast duration
       */
      public static void showToast(final Activity act, final String text, final int duration) {
         act.runOnUiThread(new Runnable() {
            public void run() {
               Toast.makeText(act, text, duration).show();
            }
         });
      }
   }

このクラスを使用すると、必要に応じて乾杯することができます。

ToastUtils.showToast(これ、「何らかのテキスト」、Toast.LENGTH_SHORT);

于 2012-08-11T05:36:33.987 に答える
0

http://developer.android.com/guide/components/processes-and-threads.htmlから:

ただし、操作が複雑になるにつれて、この種のコードは複雑になり、保守が困難になる可能性があります。ワーカー スレッドとのより複雑なやり取りを処理するには、ワーカー スレッドで Handler を使用して、UI スレッドから配信されるメッセージを処理することを検討してください。ただし、おそらく最善の解決策は、AsyncTask クラスを拡張することです。これにより、UI と対話する必要があるワーカー スレッド タスクの実行が簡素化されます。

...スキップして先へ...

doInBackground() でいつでも publishProgress() を呼び出して、UI スレッドで onProgressUpdate() を実行できます。

これがあなたのやりたいことのように思えます。

他の質問 (トピックごとに 1 つの質問のみを行うようにしてください) に関しては、Java でファイルをコピーすることは一種の解決済みの問題です。SOのスレッドの中で、これにはかなり良い答えがあると思います.Javaでファイルをコピーする標準的な簡潔な方法は?

于 2012-08-11T06:42:46.843 に答える
0

Handlerin アクティビティを作成できます。

Handler handler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what) {
        case R.string.cancel:
            //show toast
            break;
        default:
            break;
        }
    }
};

そして、次のようにスレッドから使​​用します。

handler.sendEmptyMessage(R.string.cancel);
于 2012-08-11T05:38:24.750 に答える