我有一项活动,我将从API调用中获取信息。我知道android的主线程,并知道我不应该重载它。我尝试使用线程,但我认为对于应用程序的复杂性,Asynctask将是最好的方法。
我目前正在使用Thread().run()
,但它仍然会返回'跳过x帧,在主线程中执行太多工作'。我想知道如何将Asynctask类添加到我的应用程序以获得更好的性能。我的活动使用ExpandableListView。
Home.java:
public class Home extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_act);
init();
}
void init() {
findViews();
changeFont();
clickListeners();
assignConditions("category", "all", "1");
categoryAllApiCall();
}
void categoryAllApiCall() {
RestAdapter restAdapter = new RestAdapter.Builder().setEndpoint(base_url).setLogLevel(RestAdapter.LogLevel.FULL).build();
final Category_All category_all = restAdapter.create(Category_All.class);
category_all.getFeed(file, operation_condition, all_condition, max_depth_condition, new Callback<CategoryPojo>() {
@Override
public void success(CategoryPojo categoryPojo, Response response) {
progressBar.setVisibility(View.GONE);
final CategoryPojo category = categoryPojo;
new Thread(new Runnable() {
@Override
public void run() {
category_id = Arrays.copyOf(category.getCategoryId(), category.getCategoryId().length);
category_name = Arrays.copyOf(category.getCategoryName(), category.getCategoryName().length);
parent_id = Arrays.copyOf(category.getParentId(), category.getParentId().length);
}
}).run();
prepareListData();
setAdapter();
}
@Override
public void failure(RetrofitError error) {
tv_title_header.setText(error.getMessage());
progressBar.setVisibility(View.GONE);
}
});
}
private void prepareListData() {
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<String>>();
int count = -1;
for (int i = 0; i < category_id.length; i++) {
List<String> child = new ArrayList<String>();
if (parent_id[i].equals("0")) {
count++;
listDataHeader.add(category_name[i]);
for (int j = 0; j < category_id.length; j++) {
if (parent_id[j].equals(category_id[i])) {
child.add(category_name[j]);
}
}
listDataChild.put(listDataHeader.get(count), child);
}
}
}
void setAdapter() {
elv_home_body_lay.setAdapter(new HomeExpandableListAdapter(this, listDataHeader, listDataChild));
elv_home_body_lay.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
int previousGroup = -1;
@Override
public void onGroupExpand(int groupPosition) {
if (groupPosition != previousGroup) {
elv_home_body_lay.collapseGroup(previousGroup);
}
previousGroup = groupPosition;
}
});
elv_home_body_lay.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
Intent intent = new Intent(Home.this, ProductListing.class);
Bundle bundle = new Bundle();
bundle.putString("operation_condition", "productlisting");
bundle.putString("catids_condition", category_id[childPosition]);
bundle.putString("catname", category_name[childPosition]);
bundle.putString("start_row_condition", "0");
bundle.putString("limit_condition", "10");
intent.putExtras(bundle);
startActivity(intent);
return false;
}
});
}
}
HomeExpandableListAdapter.java
public class HomeExpandableListAdapter extends BaseExpandableListAdapter
{
private Context context;
private List<String> listDataHeader;
private HashMap<String, List<String>> listDataChild;
public HomeExpandableListAdapter(Context context, List<String> listDataHeader, HashMap<String, List<String>> listChildData) {
this.context = context;
this.listDataHeader = listDataHeader;
this.listDataChild = listChildData;
}
@Override
public Object getChild(int groupPosition, int childPosititon)
{
return this.listDataChild.get(this.listDataHeader.get(groupPosition)).get(childPosititon);
}
@Override
public long getChildId(int groupPosition, int childPosition)
{
return childPosition;
}
@Override
public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent)
{
final String childText = (String) getChild(groupPosition, childPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.home_child_items_lay, null);
}
TextView txtListChild = (TextView) convertView.findViewById(R.id.lblListItem);
txtListChild.setTypeface(EasyFonts.robotoLight(context));
txtListChild.setText(childText);
return convertView;
}
@Override
public int getChildrenCount(int groupPosition)
{
return this.listDataChild.get(this.listDataHeader.get(groupPosition)).
size();
}
@Override
public Object getGroup(int groupPosition)
{
return this.listDataHeader.get(groupPosition);
}
@Override
public int getGroupCount()
{
return this.listDataHeader.size();
}
@Override
public long getGroupId(int groupPosition)
{
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent)
{
String headerTitle = (String) getGroup(groupPosition);
if (convertView == null)
{
LayoutInflater infalInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.home_group_items_lay, null);
}
TextView lblListHeader = (TextView) convertView.findViewById(R.id.lblListHeader);
ImageView img=(ImageView)convertView.findViewById(R.id.imageView1);
lblListHeader.setTypeface(EasyFonts.robotoBold(context));
lblListHeader.setText(headerTitle);
if(isExpanded)
{
img.setImageResource(R.drawable.ic_remove_grey_36pt_2x);
}
if(!isExpanded)
{
img.setImageResource(R.drawable.ic_add_grey_36pt_2x);
}
return convertView;
}
@Override
public boolean hasStableIds()
{
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition)
{
return true;
}
}
以上代码适用于该时间,但会降低应用性能。如何使用Asynctask类在后台运行所有处理,只需创建可扩展的列表视图而不会重载ui线程。
答案 0 :(得分:1)
直接在线程上调用run()
只是同步执行代码(在同一个线程中),就像普通的方法调用一样。您必须使用start()
方法在后台运行。
所以改变以下方法:
new Thread(new Runnable() {
@Override
public void run() {
category_id = Arrays.copyOf(category.getCategoryId(), category.getCategoryId().length);
category_name = Arrays.copyOf(category.getCategoryName(), category.getCategoryName().length);
parent_id = Arrays.copyOf(category.getParentId(), category.getParentId().length);
}
}).run();
到:
new Thread(new Runnable() {
@Override
public void run() {
category_id = Arrays.copyOf(category.getCategoryId(), category.getCategoryId().length);
category_name = Arrays.copyOf(category.getCategoryName(), category.getCategoryName().length);
parent_id = Arrays.copyOf(category.getParentId(), category.getParentId().length);
}
}).start();
问:a之间有什么区别 thread的start()和run()方法?
答:Thread类中提供了单独的start()和run()方法 两种创建线程程序的方法。 start()方法启动 执行新线程和调用 run()方法。 start()方法 立即返回和新线程 通常一直持续到运行() 方法返回。
Thread类的run()方法什么都不做,所以子类应该 用代码覆盖方法 在第二个线程中执行。如果一个 线程用Runnable实例化 参数,线程的run()方法 执行的run()方法 新线程中的Runnable对象 代替。
根据线程程序的性质,调用Thread run()方法直接可以给出 与通过start()调用相同的输出 方法,但在后一种情况下 代码实际上是以新的方式执行的 线程。
如果您想要实施AsyncTask
,请参阅This
答案 1 :(得分:0)
您可以扩展AsyncTask类以实现后台进程。
public class YourLongTask extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(String... urls) {
//run some long operation here on background
return "return some value to post execute function. change type based on your needs";
}
@Override
protected void onPostExecute(String result) {
// update your view here after on main thread after you have done long task
}
}
你可以这样称呼它
YourLongTask task = new YourLongTask().execute();
有关AsyncTask
参数的信息。
android.os.AsyncTask<Params, Progress, Result>
Params,执行时发送给任务的参数类型。
进展,期间发布的进度单位的类型 背景计算。
结果,后台计算结果的类型。