2013-05-31 3 views
0

Я пытаюсь изменить шрифты элементов списка. Без AsyncTasc это занимает слишком много времени. Использование AsyncTask с этим списком быстро появляется, а затем после сбоя приложения. Я знаю, что я не могу изменить интерфейс пользователя из AsyncTasc напрямую. Что я могу использовать? Заранее спасибоAsynctask внутри класса Adapterview

import ru.ayratbadykov.feedhandler.FEED; 
import ru.ayratbadykov.feedhandler.RssMessage; 
import android.content.Context; 
import android.graphics.Typeface; 
import android.os.AsyncTask; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.TextView; 

public class CustomAdapter extends BaseAdapter { 
    private FEED _data; 
    Context _c; 

    CustomAdapter(FEED data, Context c) { 
     _data = data; 
     _c = c; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     // TODO Auto-generated method stub 
     Log.w("here","here"); 
     View v = convertView; 
     if (v == null) { 
      LayoutInflater vi = (LayoutInflater) _c 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = vi.inflate(R.layout.customadapter, null); 
     } 

     TextView fromView = (TextView) v.findViewById(R.id.textView1); 
     TextView subView = (TextView) v.findViewById(R.id.textView2); 
     TextView View = (TextView) v.findViewById(R.id.textView3); 

     RssMessage msg = _data.getMessages().get(position); 
     new Font().execute(fromView,subView,View); 





     fromView.setText(msg.getTitle()); 
     subView.setText(msg.getPUBDATE()); 
     View.setText(_data.getTitle()); 

     return v; 
    } 
    public class Font extends AsyncTask<TextView, Void, Boolean> { 

     @Override 
     protected Boolean doInBackground(TextView... params) { 
      // TODO Auto-generated method stub 
      String fontPath = "fonts/Qlassik_TB.ttf"; 
      Typeface tf = Typeface.createFromAsset(_c.getAssets(), fontPath); 
      params[0].setTypeface(tf); 
      fontPath="fonts/damase.ttf"; 

      tf = Typeface.createFromAsset(_c.getAssets(), fontPath); 
      params[1].setTypeface(tf); 

      tf = Typeface.createFromAsset(_c.getAssets(), fontPath); 
      params[3].setTypeface(tf); 
      return true; 

     } 

    } 

    @Override 
    public int getCount() { 
     // TODO Auto-generated method stub 
     return _data.getMessages().size(); 

    } 

    @Override 
    public Object getItem(int position) { 
     // TODO Auto-generated method stub 
     return _data.getMessages().get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     // TODO Auto-generated method stub 
     return position; 
    } 
} 

журнал

05-31 22:32:27.602: E/AndroidRuntime(2803): FATAL EXCEPTION: AsyncTask #1 
    05-31 22:32:27.602: E/AndroidRuntime(2803): java.lang.RuntimeException: An error occured while executing doInBackground() 
    05-31 22:32:27.602: E/AndroidRuntime(2803):  at android.os.AsyncTask$3.done(AsyncTask.java:200) 
    05-31 22:32:27.602: E/AndroidRuntime(2803):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
    05-31 22:32:27.602: E/AndroidRuntime(2803):  at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
    05-31 22:32:27.602: E/AndroidRuntime(2803):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
    05-31 22:32:27.602: E/AndroidRuntime(2803):  at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
    05-31 22:32:27.602: E/AndroidRuntime(2803):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
    05-31 22:32:27.602: E/AndroidRuntime(2803):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
    05-31 22:32:27.602: E/AndroidRuntime(2803):  at java.lang.Thread.run(Thread.java:1019) 
    05-31 22:32:27.602: E/AndroidRuntime(2803): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
    05-31 22:32:27.602: E/AndroidRuntime(2803):  at android.os.Handler.<init>(Handler.java:121) 
    05-31 22:32:27.602: E/AndroidRuntime(2803):  at ru.ayratbadykov.rssunion.CustomAdapter$Font$1.<init>(CustomAdapter.java:63) 
    05-31 22:32:27.602: E/AndroidRuntime(2803):  at ru.ayratbadykov.rssunion.CustomAdapter$Font.doInBackground(CustomAdapter.java:63) 
    05-31 22:32:27.602: E/AndroidRuntime(2803):  at ru.ayratbadykov.rssunion.CustomAdapter$Font.doInBackground(CustomAdapter.java:1) 
    05-31 22:32:27.602: E/AndroidRuntime(2803):  at android.os.AsyncTask$2.call(AsyncTask.java:185) 
    05-31 22:32:27.602: E/AndroidRuntime(2803):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
    05-31 22:32:27.602: E/AndroidRuntime(2803):  ... 4 more 
+0

Вы обновляете ui на фоне потока. используйте runonuithread для того же – Raghunandan

ответ

1

Вы можете обновить UI в AsyncTask просто не из doInBackground(). Но любые другие методы в порядке. И поскольку это внутренний класс вашего класса Adapter, который содержит ссылку на Context, тогда это нормально. Просто переместите код, который использует Context, или ему необходимо обновить UI любым другим способом.

Например, вы могли бы вернуть ArrayList в params к onPostExecute() и обновлять там или вы можете использовать publishProgress() и обновлять их в onProgressUpdate()

onPostExecute

onProogressUpdate

Так же есть много хорошие примеры использования каждого

+0

Не забывайте onPreExecute();) – Jarvis

+0

@ Jarvis right, вот почему я обычно говорю любой, но 'doInBackground()', но обычно указывают на эти два, поскольку, по моему опыту, они используются больше, наименее в этом типе ситуации. Но я должен, вероятно, начать явно добавлять комментарий о 'onPreExecute()', потому что это не первый раз, когда я указал на это. Благодаря! :) – codeMagic

+0

Приветствую вас, я добавил ответ, чтобы попытаться объяснить asyntack – Jarvis

0

AsyncTask позволяет вам начать длительный процесс го доступа к UI с помощью методов UIThread:

  • onPreExecute(): для обновления пользовательского интерфейса до начала вашего лечения (нити в doInBackground)
  • onProgressUpdate(): обновить пользовательский интерфейс во время лечения
  • onPostExecute(): обновить интерфейс в конце процесса.

У вас есть все, что нужно сделать, если вы понимаете работу с AsyncTask

0

Вы не можете обновить пользовательский интерфейс на фоновом потоке. doOnBackground вызывается в фоновом потоке. Вы должны обновить ui в потоке ui.

Вы пытаетесь обновить текст в doInBackground. Используйте runOnUiThread, если вам нужно обновить ui внутри doInBackground().

Я также не уверен, почему вам нужна асинтеза для того, что вы делаете.

 runOnUiThread(new Runnable(){ 

      @Override 
      public void run(){ 
      //update ui here 
      } 
     }); 

onPreExecute(), onPostExecute (результат), вызываются на поток пользовательского интерфейса. Таким образом, вы можете обновить ui здесь.

onProgressUpdate (Progress ...), вызывается в потоке пользовательского интерфейса после вызова publishProgress (Progress ...). может использоваться для анимации индикатора выполнения или отображения журналов в текстовом поле.

Результат doInbackground() вычисление является параметром onPostExecute (Result) так возвращает результат в doinBackground() и показать свой тост в onPostExecute (Result)

Для ясности проверить ссылку ниже под топика 4 шага.

http://developer.android.com/reference/android/os/AsyncTask.html

Вы также можете использовать обработчик для этой цели.

http://developer.android.com/reference/android/os/Handler.html

0

решение Conisder не создавать шрифт из актива для каждого поля. Сделать статический метод, возвращающий Typeface, например. Я устанавливаю шрифты для элементов списка без проблем с производительностью в потоке пользовательского интерфейса.

, например:

public class CustomAdapter extends BaseAdapter { 

static Typeface mFont = YourClass.getDefaultTypeFace(); 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
    ... 
    TextView tv; 
    ... 
    tv.setTypeface(mFont); 
    ... 
    } 
} 

Кроме того, есть некоторые проблемы с выделением памяти для активов шрифта, не создает умножение экземпляров Typeface. Проверьте это, отлично работает для меня: To use or not to use Custom Fonts on Android

Смежные вопросы