2012-05-04 12 views
0

UPDATE 05/08/12 7:23 AM:
ドロー/トーストを交換しようとしました。つまり、メインUIスレッドのAsyncTaskとToastに描画を入れましたが、動作は変わりませんでした。あきらめる。しかし、すべての提案に感謝します。
- ジョン描画が完了するまで延期されたトースト。どうして?

======================================

UPDATE 05/04/12 6:30 PM:
"シングルタスク"の問題が問題でワーカースレッドが動作する可能性があると考えましたが、両方のスレッドが定義上UI(メインスレッド)にアクセスする必要があるため、私はまだ私が競合しているように思えた。それにもかかわらず、提案に基づいて、のトーストをAsyncTaskのonProgressUpdate()に入れましたが、恐らく問題は解決しません。 (私はモンスターであるため非同期タスクにレンダリングをしたくないし、他のタスクで単純なトーストをするのがより快適だった)。だから、まだ喜びはありません。これを行う方法に関する他の提案はありますか?私が作成した

======================================ビットマップを作成して画面に描画するアプリケーションです。ビットマップの作成には2〜3秒かかりますので、「リフレッシュしてください、待ってください...」のようなユーザーにトーストメッセージを表示します。私の問題は、までの塗料が完成した後でトーストが表示されないことです。の前に drawBitmap()を呼び出しています。

長い計算の間にメッセージキューがバックアップされているため、Windowsでは、このような動作が発生しています。解決策は、定期的に、長い計算中にメッセージを明示的にディスパッチすることでした。しかし、Androidでこれを行うかどうかはわかりません。多分神秘的な(私に) "ルーパー" ???

私は、問題を特定/除外する、小さくて軽いアプリを含めました。

いずれかの提案大幅にが評価されました。
- ジョン

// PixmapTestMain.java 

public class PixmapTestMain extends Activity { 

public static View PixmapView;     // pixmap view 
public static Context Ctx; 

// Create activity 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    Ctx = this; 
    PixmapView = findViewById(R.id.pixmap); 
} 

// Handle click 
public void onClick(View v) {   // button view clicked 
    PixmapView.invalidate();   // new pixmap 
} 

} // end class PixmapTestMain 

カスタムビュー:

// PixmapView - my custom view 

public class PixmapView extends View { 

static final int Wide=1000,High=1000,Size=(Wide*High); 
static int toggle; 

// Construct a view to display pixmap 
public PixmapView(Context ctx,AttributeSet attrs) { 
    super(ctx, attrs); 
} 

// Handle onDraw callback 
@Override 
protected void onDraw(Canvas canvas) { 
    int[] pixmap; 
    Bitmap bm; 

    super.onDraw(canvas); 

    toast("Refreshing..."); 
    pixmap = createPixmap(); 
    bm = Bitmap.createBitmap(pixmap, Wide, High, Bitmap.Config.ARGB_8888); 
    canvas.drawBitmap(bm, 0, 0, null); 
} 

// Create a pixmap 
int[] createPixmap() 
{ 
    int i,color; 
    int[] pm; 
    double s; 
    Random rand = new Random(); 

    pm = new int[Size];      // allocate pixmap 

    toggle++; 
    if((toggle&1)==0) color = 0xff0000ff; // red 
    else    color = 0xffff0000; // blue 

    for(i=0; i<Size; i++) { 
     pm[i] = color; 
     rand.nextLong();  // slow me down 
    } 

    return(pm); 
} 

// Flash a toast message 
public void toast(String msg) 
{ 
    if(PixmapTestMain.Ctx == null) return; 
    Toast.makeText(PixmapTestMain.Ctx, msg, 0).show(); 
    } 
} 

レイアウト:

<?xml version="1.0" encoding="utf-8"?> 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent"> 

<Button 
    android:text="Refresh" 
    android:id="@+id/refresh" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:onClick="onClick"/> 

<com.hyperdyne.PixmapTest.PixmapView 
    android:id="@+id/pixmap" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"/> 

</LinearLayout> 

答えて

1

あなたには、例えば、離れてあなたのUIスレッドから長時間実行タスクを移動する必要があります:

protected void onDraw(Canvas canvas) { 
    int[] pixmap; 
    Bitmap bm; 

    super.onDraw(canvas); 

    toast("Refreshing..."); 
    pixmap = createPixmap(); 
    bm = Bitmap.createBitmap(pixmap, Wide, High, Bitmap.Config.ARGB_8888); 
    canvas.drawBitmap(bm, 0, 0, null); 
} 

はなるはずです:

private class DrawAsyncTask extends AsyncTask<Void,Void,Bitmap[]> { 
    int[] pixmap; 
    Bitmap bm; 

    protected Void doInBackground(Void... v) { 
     pixmap = createPixmap(); 
     bm = Bitmap.createBitmap(pixmap, Wide, High, Bitmap.Config.ARGB_8888); 
     return bm; 
    } 

    protected void onPostExecute(Bitmap[] result) { 
     canvas.drawBitmap(result[0], 0, 0, null); 
    } 
} 

protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
    toast("Refreshing..."); 
    new DrawAsyncTask().execute(); 
} 
+0

ありがとうlenik、私はそれを試してみます。以前の試みでは、メインのUIタスクに図面を残し、トーストをスピンしました。あなたが提案して結果を投稿するときに、私は別の方法で試してみます。 – DontPanic

+1

'Toync'を' AsyncTask'に入れる理由はありません。かなりの時間を必要とせず、UIスレッドでうまく動作します。 'AsyncTask'に入れるべきことは、ファイルアクセス、ネットワークアクセス、複雑な計算やデータ処理のような長時間実行されるタスクです。 – lenik

0

あなたは変更が唯一見ての両方が、それらの間の遅延なしでUIに曽根されています両方の後に。

1

Toastメッセージと同じスレッドでキャンバスの更新を呼び出しています。再描画操作は、完了するまでUIスレッドをブロックするので、UIスレッドがブロック解除されるまでトーストメッセージをレンダリングすることはできません。再描画操作をワーカースレッドに移動すると、問題が解決されます。

+0

投稿の上部にある更新を参照してください。 – DontPanic

0

私は同様の問題がありました。私の場合、私はGoogleマップを読み込んでいます。初めてGoogleマップが読み込まれると、初期マップ画像の読み込みと同様に、apiキーの検証プロセスのためにかなりの遅延があります。これは数秒のオーダーを要し、トーストは表示されません。シンプルな解決策は、マップをAsyncTaskまたは別のアクティビティにロードすることですが、ではなくで、AsyncTaskまたはActivityをただちに起動しますが、1秒後に実行します。まずトーストを表示し、遅れてからプロセスを起動してください:

Toast.makeText(context, "Please wait...", Toast.LENGTH_LONG).show(); 
Handler handler = new Handler(); handler.postDelayed(DoSomething, 1000); 

private Runnable DoSomething = new Runnable() 
{ 
    @Override 
    public void run() 
    { 
    try 
    { 
     // Launch an AsyncTask here or some other activity to handle your long process. 
    } 
    catch (Exception ex) 
    { 
    } 
    } 
}; 
関連する問題