بروز خطا
   [message]
اشتراک در سوال
رای ها
[dataList]
پرسش و پاسخ

اشکال در multi threading (حل شد , مشکل در جاوا - همزمانی نبود)

مدیریت گفتگو
Unique Dev 10 سال پیش
آخرین تغییر: 10 سال پیش

سلام دوستان

این کد یه پلیر داخل اکتیویتی هستش که منتها بخاطر مشکل تو ترد هاش اهنگ هنگام پخش تیک میزنه

seekber با فاصله 1000 میلی ثانیه اپدیت میشه و تو همین زمان mediaplayer تیک میزنه

 

 img_play.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                if (G.mediaPlayer != null) {
                    if (G.mediaPlayer.isPlaying()) {
                        G.log("G.mediaPlayer.isPlaying()");
                        img_play.setImageResource(R.drawable.play_button);
                        G.log("img_play.setImageResource(R.drawable.play_button);");
                        G.mediaPlayer.pause();
                        G.log("G.mediaPlayer.pause();");
                    } else {
                        G.log(" else !G.mediaPlayer.isPlaying()");
                        img_play.setImageResource(R.drawable.pause_button);
                        G.log("img_play.setImageResource(R.drawable.pause_button);");
                        startMediaPlayer();
                        G.log("G.mediaPlayer.startMediaPlayer();");
                        handler.post(runnable);
                        G.log("updateSeekbar();");
                    }
                } else {
                    createNewMediaPlayer(pathSong);
                }
            }
        });

.
.
.


private void startMediaPlayer() { // TODO Auto-generated method stub seekbar_play.setMax(G.mediaPlayer.getDuration()); setImgPause(); G.mediaPlayer.start(); }

.
.
.

Runnable runnable = new Runnable() { @Override public void run() { // TODO Auto-generated method stub if (G.mediaPlayer != null) { if ( !G.mediaPlayer.isPlaying()) return; G.log("handler post"); int mCurrentPosition = G.mediaPlayer.getCurrentPosition(); seekbar_play.setProgress(mCurrentPosition); int finalTime = G.mediaPlayer.getDuration(); int startTime = G.mediaPlayer.getCurrentPosition(); txt_time_duration.setText(String.format("%02d:%02d", TimeUnit.MILLISECONDS.toMinutes((long) finalTime), TimeUnit.MILLISECONDS.toSeconds((long) finalTime) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) finalTime))) ); txt_time_now.setText(String.format("%02d:%02d", TimeUnit.MILLISECONDS.toMinutes((long) startTime), TimeUnit.MILLISECONDS.toSeconds((long) startTime) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) startTime))) ); } handler.postDelayed(this, 1000); } };

نظرات

Unique Dev 10 سال پیش
کسی از عهده جاوا - همزمانی برنمیاد؟

پاسخ‌ها 5

hamidd 10 سال پیش

سلام .

موضوع اول این که اصلا دیزاین پترن خوبی  برای update کردن seekbar ننوشتین.

 

دوم این که از handler استفاده کردین دلیل بر این نمیشه که کدتون توی یک ترد به غیر از ترد main داره اجرا میشه. کدهای handler توی همون تردی اجرا میشن که handler اونجا تعریف شده باشه.

handler تون رو 100 درصد توی ترد main تعریف کردید پس کد ها در ترد main اجرا میشن و برنامه لگ داره.

طبق مستندات 

public final boolean postDelayed (Runnable r, long delayMillis)

Causes the Runnable r to be added to the message queue, to be run after the specified amount of time elapses. The runnable will be run on the thread to which this handler is attached. The time-base is uptimeMillis(). Time spent in deep sleep will add an additional delay to execution.

کدهای داخل runnable که از طریق تابع postDelayed (Runnable r, long delayMillis) فراخوانی میشن روی همون تردی که handler بهش attach شده باشه اجرا میشن ... بالا توضیح دادم

 

یک ترد ایجاد کنید و داخل اون ترد ، ui رو آپدیت کنید (که شما همون seekbar رو آپدیت می کنید)

 

نظرات

Unique Dev 10 سال پیش
اپدیت کردن سیک بار که باید تو ترد ui انجام بشه من سعی کردم مدیا پلیرم رو تو یه ترد دیگه استارت کنم که نشد کلا یعنی دیگه اپدیت نشد سیک بارم
hamidd 10 سال پیش
نه دوست عزیز . من خودم کدشو نوشتم تو موزیک پلیر برنامه ام . توی یک ترد دیگه seekbar و آپدیت می کنم .
Unique Dev 10 سال پیش
خب من handler رو توی کلاس G تعریف کردم باز هم نشد! بازم لگ داره! تازه فقط سیک بار نیس شمارش ثانیه ها هستن
Unique Dev 10 سال پیش
نمیشه مدیا پلیر رو یه کاریش کنیم؟
hamidd 10 سال پیش
ببینید شما handler و متد postDelayed رو بی خیال بشید و از ترد استفاده کنید و اگه آموزش ها رو ندیدید ببینید حتما. یه ترد بنویسید و یه حلقه ی while داخلش . توی حلقه ی while ، ترد رو هر بار 1000 میلی ثانیه sleep کنید و بعد seekbar رو آپدیت کنید . از این دیگه آسون تر
Unique Dev 10 سال پیش
خب من همین راه شما امتحان کردم ولی دیگه نمیشه از ترد جداگانه textview های ثانیه هارو عوض کرد دیگه لگ نداره ولی این باگ رو داد Only the original thread that created a view hierarchy can touch its views.
hamidd 10 سال پیش
اگه آموزش ها رو دیده باشید، گفته شده که برای آپدیت کردن ui (در تردی به غیر از ترد main ) ، باید یک handler در ترد main تعریف کنین و کدهاتونو به handler پاس بدین تا کرش نکنه و این خطا رو نده. آموزش ها رو ندیدین . توضیح داده شده اونجا
Unique Dev 10 سال پیش
من اموزشارو دقیق دیدم و از رو همون اطلاعاتی که دارم میگم نمیشه (hamidd : یه ترد بنویسید و یه حلقه ی while داخلش . توی حلقه ی while ، ترد رو هر بار 1000 میلی ثانیه sleep کنید و بعد seekbar رو آپدیت کنید . ) + textview ثانیه هارو عوض کنیم بخاطر همین از (hamidd: باید یک handler در ترد main تعریف کنین و کدهاتونو به handler پاس بدین تا کرش نکنه و این خطا رو نده.) استفاده کردم اونم برای همون اول نه وقتی که شما گفتی handler رو هم که داخل ترد main تعریف کنم بازم میشه اول داستان و تازه با این(hamidd : ببینید شما handler و متد postDelayed رو بی خیال بشید و از ترد استفاده کنید و اگه آموزش ...) تناقض داره
hamidd 10 سال پیش
اگه آموزش ها رو دیدین، الان شما کجا از ترد استفاده کردین . اون خطی که از ترد استفاده کردین و نشون بدین D: من میگم به طور کلی بهتره از ترد استفاده کنین :) و با یه حلقه while ...
Unique Dev 10 سال پیش
استفاده کردم میتونین تو اخرین پست ببینیدش
hamidd 10 سال پیش
خوب خوبه . الان کد آپدیت کردن seekbar رو همون طور که توی آموزش ها گفته شده توی handler بزارید و تمام
Unique Dev 10 سال پیش
مشکل از جاهای دیگه ست فک کنم خیلی عجیب شده نمیدونم چه کار کنم تمام کارارو امتحان کردم یه کدی رو از یه جایی پیدا کردم و مثل اون کدم رو نوشتم ولی بازم لگ داره
Unique Dev 10 سال پیش
hamidd جان مشکلم حل شد ممنون بابت پبگیریت :)
Unique Dev 10 سال پیش

سلام ممنون ازین که وقت گذاشتین جواب دادین

اول اینکه دیزاین پترنم برا اپدیت کردن سیک بار چه مشکلی داره؟

من کدم رو به این شکل در اوردم . ببینید یه جای دیگه هم تو برنامم میخوام یه اهنگ دیگه رو با async task دانلود کنم ولی این پلیره متوقف میشه کلا متوجه نمیشم کدوم باید تو کدوم ترد اجرا بشه

 private void updateSeekbar() {
        // TODO Auto-generated method stub

        seekbar_play.setMax(G.mediaPlayer.getDuration());
        ActivityPlay.this.runOnUiThread(new Runnable() {

            @Override
            public void run() {
                if (G.mediaPlayer != null) {
                    if ( !G.mediaPlayer.isPlaying())
                        return;
                    int mCurrentPosition = G.mediaPlayer.getCurrentPosition();
                    seekbar_play.setProgress(mCurrentPosition);
                    int finalTime = G.mediaPlayer.getDuration();
                    int startTime = G.mediaPlayer.getCurrentPosition();
                    txt_time_duration.setText(String.format("%02d:%02d", TimeUnit.MILLISECONDS.toMinutes((long) finalTime),
                            TimeUnit.MILLISECONDS.toSeconds((long) finalTime) -
                                    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) finalTime)))
                            );
                    txt_time_now.setText(String.format("%02d:%02d", TimeUnit.MILLISECONDS.toMinutes((long) startTime),
                            TimeUnit.MILLISECONDS.toSeconds((long) startTime) -
                                    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) startTime)))
                            );
                }
                handler.postDelayed(this, 1000);
            }
        });
    }
 

نظرات

Unique Dev 10 سال پیش

 private void updateSeekbar() {
        // TODO Auto-generated method stub

        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                seekbar_play.setMax(G.mediaPlayer.getDuration());
                while (true) {
                    G.log("update");
                    if (G.mediaPlayer != null) {
                        if ( !G.mediaPlayer.isPlaying())
                            return;
                        int mCurrentPosition = G.mediaPlayer.getCurrentPosition();
                        seekbar_play.setProgress(mCurrentPosition);
                        int finalTime = G.mediaPlayer.getDuration();
                        int startTime = G.mediaPlayer.getCurrentPosition();
                        /*txt_time_duration.setText(String.format("%02d:%02d", TimeUnit.MILLISECONDS.toMinutes((long) finalTime),
                                TimeUnit.MILLISECONDS.toSeconds((long) finalTime) -
                                        TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) finalTime)))
                                );*/
                        /*txt_time_now.setText(String.format("%02d:%02d", TimeUnit.MILLISECONDS.toMinutes((long) startTime),
                                TimeUnit.MILLISECONDS.toSeconds((long) startTime) -
                                        TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) startTime)))
                                );*/
                    }

                    try {
                        Thread.sleep(1000);
                    }
                    catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }
            }
        });
        thread.start();

 

که ارور میده

نظرات

Unique Dev 10 سال پیش

دیگه واقعا دارم دیوونه میشم

یه خط کدو یه جا میزارم لگ میزنه برش میدارم یه جا دیگه میزارم لگ نمیزنه

کد startFull رو نگاه کنید

 //startFull(pathSong);
        if (new File(pathSong).exists()) {
            G.log("if (new File(pathSong).exists()) ");
            orderButtonsPlay();
            G.log("orderButtonsPlay();");
            if (G.mediaPlayer != null) {
                G.log("if (G.mediaPlayer != null)");
                int duration = MediaPlayer.create(G.context, Uri.parse(pathSong)).getDuration();
                int last_duration = G.mediaPlayer.getDuration();
                if (G.mediaPlayer.isPlaying()) {
                    G.log("if (G.mediaPlayer.isPlaying())");
                    if (duration == last_duration) {
                        G.log("if duration == last_duration");
                        //nothing
                        setImgPause();
                        MainActivity.myHandler.postDelayed(UpdateSongTime, 1000);
                        //updateSeekbar();
                    } else {
                        G.log("else duration != last_duration");
                        G.mediaPlayer.stop();
                        G.log("G.mediaPlayer.stop();");
                        G.mediaPlayer.reset();
                        G.log("G.mediaPlayer.reset();");
                        createNewMediaPlayer(pathSong);
                        G.log("createNewMediaPlayer();");
                        startMediaPlayer();
                        G.log("startMediaPlayer();");
                        MainActivity.myHandler.postDelayed(UpdateSongTime, 1000);
                        //updateSeekbar();
                        G.log("updateSeekbar();");

                    }
                } else {
                    G.log("else is playing");
                    if (duration == last_duration) {
                        G.log("if duration == last_duration");
                        startMediaPlayer();
                        G.log("startMediaPlayer();");
                        MainActivity.myHandler.postDelayed(UpdateSongTime, 1000);
                        //updateSeekbar();
                        G.log("updateSeekbar();");
                    } else {
                        G.log("else duration != last_duration");
                        G.mediaPlayer.reset();
                        G.log("G.mediaPlayer.reset();");
                        createNewMediaPlayer(pathSong);
                        G.log("createNewMediaPlayer();");
                        startMediaPlayer();
                        G.log("startMediaPlayer();");
                        MainActivity.myHandler.postDelayed(UpdateSongTime, 1000);
                        //updateSeekbar();
                        G.log("updateSeekbar();");
                    }
                }
            }
            else {

                startFull(pathSong);
                G.log("else media== null");
                /*
                createNewMediaPlayer(pathSong);
                G.log("createNewMediaPlayer();");
                startMediaPlayer();
                G.log("startMediaPlayer();");
                MainActivity.myHandler.postDelayed(UpdateSongTime, 1000);
                //updateSeekbar();
                G.log("updateSeekbar();");*/
            }
        }
        else {
            G.log("else new file not exist");
            orderButtonsDownload();
            G.log("orderButtonsDownload();");
        }

 

 public void startFull(String pathSong) {
        G.mediaPlayer = MediaPlayer.create(G.context, Uri.parse(pathSong));
        G.mediaPlayer.start();
        seekbar_play.setMax(G.mediaPlayer.getDuration());
        myHandler.postDelayed(UpdateSongTime, 100);
    }
 private Runnable UpdateSongTime = new Runnable() {

                                        @Override
                                        public void run() {
                                            G.log("handler post");
                                            int startTime = G.mediaPlayer.getCurrentPosition();
                                            txt_time_now.setText(String.format("%d min, %d sec",

                                                    TimeUnit.MILLISECONDS.toMinutes((long) startTime),
                                                    TimeUnit.MILLISECONDS.toSeconds((long) startTime) -
                                                            TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.
                                                                    toMinutes((long) startTime)))
                                                    );
                                            seekbar_play.setProgress((int) startTime);
                                            MainActivity.myHandler.postDelayed(this, 100);
                                        }
                                    };

نظرات

Unique Dev 10 سال پیش

خداروشکر

اقا واقعا توسل و دعای مادر تاثیر داره ها

به مادرم گفتم سه سوت نشد گرهم باز شد

مشکل ازین جا بود

دلیل لگ زدن نه ترد بود نه هندلر

این بود

 seekbar_play.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

            @Override
            public void onStopTrackingTouch(SeekBar arg0) {
                // TODO Auto-generated method stub

            }


            @Override
            public void onStartTrackingTouch(SeekBar arg0) {
                // TODO Auto-generated method stub

            }


            @Override
            public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
                // TODO Auto-generated method stub
           >>>>>     if (G.mediaPlayer != null)
                    G.mediaPlayer.seekTo(arg1);
            }
        });

نظرات


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