آموزش های این وب سایت به صورت رایگان در دسترس است. اطلاعات بیشتر
بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]

کرش در Thread و Canvas

Hadi  9 سال پیش  9 سال پیش
0 0

سلام دوستان. وقتی کد زیر رو اجرا میکنه برنامه کرش میکنه. دلیلش رو اصلا نمیدونم اما میدونم که از خط کشیدن Arc کرش میکنه. چون اگر اون رو بردارم یا خارج از هندلر و Thread بنویسم کرش نمیکنه. اما چون میخوام انیمشن دادن رو تمرین کنم میخوام عمل کنه. متشکر

 
package test1.com.hadi.canvastest;


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.widget.ImageView;

public class CanvasView extends ImageView {
public Paint fillPaint;
int in = 0;

public CanvasView(Context context) {
super(context);
init();
}

public CanvasView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}

public CanvasView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}


public void init() {
fillPaint = new Paint();
fillPaint.setColor(Color.parseColor("#000fff"));
fillPaint.setStyle(Paint.Style.FILL);
fillPaint.setStrokeWidth(5);
}

@Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);

int centerX = getWidth() / 2;
int centerY = getHeight() / 2;
int radius = 300;
final RectF rect = new RectF(centerX - radius, centerY - radius, centerX + radius, centerY + radius);

Thread thread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i <= 90; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

MainActivity.handler.post(new Runnable() {
@Override
public void run() {
in += 1;
canvas.drawArc(rect, 0, in, false, fillPaint);
}
});
}
}
});
thread.start();


}
}
 
0 0
شما نمیتونید تغییرات ui رو در تردی غیر از ترد ui انجام بدید. دلیل کرش برنامه هم اینه مه شما دارید عملیات draw رو توی ترد دیگه ای انجام میدید. البته در کل روش ایجاد انیمیشن شما اشتباهه ، بهتره یه جستجو درباره valueAnimator بکنید و از اون روش استفاده کنید. (9 سال پیش)
+1 0
اگر دقت کنید از طریق هندلر static در MainActivityتغیرات رو انجام دادم. اما باز هم کرش میکنه. (9 سال پیش)
+1 0
درسته من دقت نکردم به کدتون. در هر صورت پیشنهاد من اینه که از ترد استفاده نکنید برای ایجاد انیمیشن و از valueAnimator استفاده کنید. (9 سال پیش)
0 0
انیمیشنی که مد نظر شماست با من فرق داره. من منظورم خلاقیت با Canvas هست. به هر حال ممنون که وقت گذاشتید.متشکر (9 سال پیش)
0 0
اتفاقا دقیقا همین کاری که شما دارید میکنید رو براتون انجام میده (9 سال پیش)
0 0
اوکی در موردش سرچ می کنم. (9 سال پیش)
 برای این سوال 1 پاسخ وجود دارد. مشاهده پاسخ صحیح
پاسخ به سوال 
Reza  9 سال پیش
+2 0

 پاسخ صحیح

سلام ، در متد onDraw نیازی به استفاده از thread نیست ، و اصلا اشتباهه استفاده از thread در onDraw . چون onDraw هر موقع به طور کامل اجرا بشه چیزی رسم میکنه ، نه از طریق یک thread . وقتی شما در اولین اجرای پیش فرض onDraw ، به دستور thread.start() میرسی ، دیگه متد onDraw تموم شده و چیزی رسم نشده . حالا اینکه یک thread تعریف شده که یه چیزی رسم کنه ، کار نمیکنه ، چون ترسیم باید از طریق متد onDraw انجام بشه . که کار متد invalidate همینه ، که کل متد  onDraw رو دوباره صدا میزنه . متد onDraw رو به این صورت تغییر بده :

 @Override
    protected void onDraw(final Canvas canvas) {
        super.onDraw(canvas);

        int centerX = getWidth() / 2;
        int centerY = getHeight() / 2;
        int radius = 50;
        final RectF rect = new RectF(centerX - radius, centerY - radius, centerX + radius, centerY + radius);

        try {
            Thread.sleep(1000);
            canvas.drawArc(rect, 0, in, false, fillPaint);
            in += 1;
            invalidate();
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
}

در ضمن برای کارایی بهتر ، خوبه که centerX و centerY و radius و rect رو فیلد کنی و در متد init مقدار بدی .

+1 0
حق با شماست. . کدی که گذاشتم تمیز نبود.نباید هم بود. چون برا تمرین و آشنایی استفاده کرده بودم.خیلی ممنون از کدتون (9 سال پیش)

پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .