我正在尝试更改listview项的字体。如果没有AsyncTasc,则需要花费太多时间。在列表视图中使用AsyncTask活动会快速出现,然后在实例应用程序崩溃后出现。我知道我不能直接从AsyncTasc更改UI。我可以使用什么?提前致谢
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 :(得分:1)
您可以更新UI
中的AsyncTask
,而不是doInBackground()
。但任何其他方法都没问题。因为它是Adapter
类的内部类,它包含对Context
的引用,所以可以这样做。只需移动使用Context
的代码或需要将UI
更新为任何其他方法。
例如,您可以将ArrayList
的{{1}}返回到params
并在那里更新,或者您可以使用onPostExecute()
并在publishProgress()
<更新它们/ p>
所以也有很多使用每个
的好例子答案 1 :(得分:0)
AsyncTask允许您通过UIThread方法启动长进程并访问UI:
如果您了解Asynctask的操作,您就拥有了所需要做的一切
答案 2 :(得分:0)
您无法在后台线程上更新ui。在后台线程上调用doInBackground。你应该在ui线程上更新ui。
您正在尝试更新doInBackground中的textview。如果需要在doInBackground()中更新ui,请使用runOnUiThread。
我也不确定为什么你需要一个asynctask来做你正在做的事情。
runOnUiThread(new Runnable(){
@Override
public void run(){
//update ui here
}
});
在ui线程上调用onPreExecute(),onPostExecute(Result)。所以你可以在这里更新ui。
onProgressUpdate(Progress ...),在调用publishProgress(Progress ...)后在UI线程上调用。可用于为进度条设置动画或在文本字段中显示日志。
doInbackground()计算的结果是onPostExecute(Result)的参数,所以在doinBackground()中返回结果并在onPostExecute(Result)中显示你的toast
为清楚起见,请查看以下主题“4个步骤”下的链接。
http://developer.android.com/reference/android/os/AsyncTask.html
您也可以使用处理程序。
http://developer.android.com/reference/android/os/Handler.html
答案 3 :(得分:0)
Conisder解决方案不为每个字段创建资产字体。 例如,使静态方法返回Typeface。 我正在为列表元素设置字体,在UI线程中没有性能问题。
例如:
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);
...
}
}
此外,字体资源的内存分配存在一些问题,请勿创建字体的多个实例。检查一下,对我来说非常适合: To use or not to use Custom Fonts on Android