سؤال

حاولت أن أفعل هذا

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    t=new TextView(this); 

    t=(TextView)findViewById(R.id.TextView01); 
    t.setText("Step One: blast egg");

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

    t.setText("Step Two: fry egg");

ولكن لسبب ما ، يظهر النص الثاني فقط عند تشغيله. أعتقد أنه قد يكون له علاقة مع Thread.sleep() طريقة حظر. فهل يمكن لأي شخص أن يريني كيفية تنفيذ مؤقت "بشكل غير متزامن"؟

شكرًا.

هل كانت مفيدة؟

المحلول

لقد نشرت هذه الإجابة للتو في مجموعة Google Android-discuss

إذا كنت تحاول فقط إضافة نص إلى العرض بحيث يعرض "الخطوة الأولى: Blast Egg Step: t.appendText("Step Two: fry egg"); بدلاً من t.setText("Step Two: fry egg");

إذا كنت تريد تغيير ما هو موجود تمامًا في TextView بحيث تقول "الخطوة الأولى: Blast Egg" عند بدء التشغيل ثم تقول "الخطوة الثانية: تقلى البيض" في وقت لاحق يمكنك دائمًا استخدام ملف

مثال قابل للتشغيل أعطى Sadboy

حظا طيبا وفقك الله

نصائح أخرى

لك onCreate() الطريقة لها العديد من العيوب الضخمة:

1) onCreate يجهز نشاطك - لذلك لا شيء تفعله هنا مرئي للمستخدم حتى تنتهي هذه الطريقة! على سبيل المثال - لن تتمكن أبدًا من تغيير أ TextViewنص هنا أكثر من واحد الوقت حيث سيتم رسم التغيير الأخير فقط وبالتالي مرئي للمستخدم!

2) ضع في اعتبارك أن برنامج Android سوف - بشكل افتراضي - تشغيل في واحد الموضوع فقط! وبالتالي: لا تستخدم أبدا Thread.sleep() أو Thread.wait() في موضوعك الرئيسي الذي هو المسؤول عن واجهة المستخدم الخاصة بك! (اقرأ "حافظ على استجابة تطبيقك" لمزيد من المعلومات!)

ماذا انت التهيئة من نشاطك هو:

  • بدون سبب لإنشاء جديد TextView هدف t!
  • أنت تختار تخطيطك TextView في المتغير t في وقت لاحق.
  • قمت بتعيين نص t (لكن ضع في اعتبارك: سيتم عرضه فقط بعد onCreate() التشطيبات وحلقة الحدث الرئيسية لتطبيقك تعمل!)
  • أنت تنتظر 10 ثواني داخل الخاص بك onCreate الطريقة - هذا يجب ألا يتم ذلك أبدًا نظرًا لأنه يتوقف عن جميع نشاط واجهة المستخدم وسيجبر بالتأكيد ANR (التطبيق لا يستجيب ، انظر الرابط أعلاه!)
  • ثم قمت بتعيين نص آخر - سيتم عرض هذا النطاق بمجرد أن onCreate() الطريقة تنتهي والعديد من الآخرين دورة حياة النشاط تمت معالجة الطرق!

الحل:

  1. تعيين النص مرة واحدة فقط في onCreate() - يجب أن يكون هذا هو النص الأول الذي يجب أن يكون مرئيًا.

  2. إنشاء Runnable و Handler

    private final Runnable mUpdateUITimerTask = new Runnable() {
        public void run() {
            // do whatever you want to change here, like:
            t.setText("Second text to display!");
        }
    };
    private final Handler mHandler = new Handler();
    
  3. تثبيت هذا التشغيل كمعالج ، ممكن في onCreate() (لكن اقرأ نصيحتي أدناه):

    // run the mUpdateUITimerTask's run() method in 10 seconds from now
    mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);
    

نصيحة: تأكد من أنك تعرف Activityدورة حياة! إذا كنت تفعل أشياء من هذا القبيل في onCreate()سيحدث هذا فقط عندما Activity يتم إنشاؤه أول الوقت! قد يحتفظ Android Activity على قيد الحياة لفترة أطول من الزمن ، حتى لو لم يكن مرئيًا! عندما "يبدأ" المستخدم مرة أخرى - وما زال موجودًا - فلن ترى النص الأول بعد الآن!


=> قم دائمًا بتثبيت معالجات في onResume() وتعطيلهم onPause()! وإلا ستحصل على "تحديثات" عندما تكون Activity غير مرئي على الإطلاق! في حالتك ، إذا كنت تريد رؤية النص الأول مرة أخرى عند إعادة تنشيطه ، فيجب عليك تعيينه في onResume(), ، ليس onCreate()!

السطر الأول من عرض النص الجديد غير ضروري

t=new TextView(this); 

يمكنك فقط القيام بذلك

TextView t = (TextView)findViewById(R.id.TextView01);

بقدر ما يكون موضوع الخلفية الذي ينام هنا مثالًا ، لكنني أعتقد أن هناك مؤقتًا سيكون أفضل لهذا الغرض. فيما يلي رابط إلى مثال جيد باستخدام مؤقت بدلاً من ذلكhttp://android-developers.blogspot.com/2007/11/stitch-in-tim.html

    Thread thr = new Thread(mTask);
    thr.start();
}

Runnable mTask = new Runnable() {
    public void run() {
        // just sleep for 30 seconds.
                    try {
                        Thread.sleep(3000);
                        runOnUiThread(done);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
        }
    };

    Runnable done = new Runnable() {
        public void run() {
                   // t.setText("done");
            }
        };

@user264892

لقد وجدت أنه عند استخدام متغير سلسلة ، احتجت إما إلى بادئة بسلسلة من "" أو تم إلقاؤها بشكل صريح إلى charsequence.

لذا بدلاً من:

String Status = "Asking Server...";
txtStatus.setText(Status);

محاولة:

String Status = "Asking Server...";
txtStatus.setText((CharSequence) Status);

أو:

String Status = "Asking Server...";    
txtStatus.setText("" + Status);

أو ، بما أن سلسلةك ليست ديناميكية ، بل أفضل:

txtStatus.setText("AskingServer...");

حسب نصيحتك ، أستخدم Handle و Runables لتبديل/تغيير محتوى TextView باستخدام "مؤقت". لسبب ما ، عند التشغيل ، يتخطى التطبيق دائمًا الخطوة الثانية ("الخطوة الثانية: تقلي البيض") ، ويظهر فقط الخطوة الأخيرة (الثالثة) ("الخطوة الثالثة: خدمة البيض").

TextView t; 
private String sText;

private Handler mHandler = new Handler();

private Runnable mWaitRunnable = new Runnable() {
    public void run() {
        t.setText(sText);
    }
};

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    mMonster = BitmapFactory.decodeResource(getResources(),
            R.drawable.monster1);

    t=new TextView(this); 
    t=(TextView)findViewById(R.id.TextView01); 

    sText = "Step One: unpack egg";
    t.setText(sText);

    sText = "Step Two: fry egg";        
    mHandler.postDelayed(mWaitRunnable, 3000);

    sText = "Step three: serve egg";
    mHandler.postDelayed(mWaitRunnable, 4000);      
    ...
}

:) تستخدم الموضوع بطريقة خاطئة. فقط افعل ما يلي:

private void runthread()
{

splashTread = new Thread() {
            @Override
            public void run() {
                try {
                    synchronized(this){

                        //wait 5 sec
                        wait(_splashTime);
                    }

                } catch(InterruptedException e) {}
                finally {
                    //call the handler to set the text
                }
            }
        };

        splashTread.start(); 
}

هذا هو.

يعد إعداد النص إلى Sam TextView مرتين في الكتابة الأولى المكتوبة. لذا في المرة الثانية التي نستخدم فيها setText ، نقوم فقط بإلحاق السلسلة الجديدة مثل

textview.append("Step Two: fry egg");

zordididiambda الإجابة رائعة ، لكنني وجدت أنه إذا وضعت

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);

في طريقة التشغيل () و

mHandler.postDelayed(mUpdateUITimerTask, 0);

في طريقة onCreate ، اجعل الشيء يستمر في التحديث.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top