【问题标题】:Adding Asynctask functionality?添加 Asynctask 功能?
【发布时间】:2015-07-30 19:16:40
【问题描述】:

我有一项活动,我将从 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 线程。

【问题讨论】:

    标签: java android multithreading android-asynctask


    【解决方案1】:

    在 Thread 上直接调用 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 之间有什么区别 线程的 start() 和 run() 方法?

    A: Thread 类中单独的 start() 和 run() 方法提供 创建线程程序的两种方法。 start() 方法启动 执行新线程和调用 run() 方法。 start() 方法 立即返回和新线程 通常会持续到 run() 方法返回。

    Thread 类的 run() 方法什么都不做,所以子类应该 用代码覆盖该方法 在第二个线程中执行。如果一个 使用 Runnable 实例化线程 参数,线程的 run() 方法 执行 run() 方法 新线程中的可运行对象 而是。

    根据线程程序的性质,调用 Thread run() 方法可以直接给出 与通过 start() 调用相同的输出 方法,但在后一种情况下 代码实际上是在一个新的 线程。

    如果你想实现AsyncTask,请查看This

    【讨论】:

    • 好的,我确实试过了,但我怎么知道何时设置适配器()。我什么时候知道线程已经完成了它的任务
    • 你不能,你可以使用 AsyncTask 类来清洁代码,但是你可以在后台线程中工作后使用 handler 或 runOnUiThread 并在线程中更新 ui
    • 好的,所以我可以通过将 run() 更改为 start() 并在 runOnUiThread 中调用 prepareListData() 和 setAdapter() 来创造更好的性能?
    • 是的@user2132383。你是对的,但这并不是比 AsyncTask 更好的性能,(我不知道女巫实际上有更好的性能)。但是正如我在回答中所说的那样,开始的betterrun 多。
    • 没用 :( 我所做的只是更改 run() 以启动并添加 runOnUiThread(new Runnable() { @Override public void run() { prepareListData(); setAdapter(); } });
    【解决方案2】:

    您可以扩展 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,执行时发送给任务的参数类型。

    进度,进度单元的类型 后台计算。

    Result,后台计算结果的类型。

    【讨论】:

    • api 调用将返回一个 String[] 所以我需要进行单独的模型调用并创建 arraylist 以用作 doinBackground() 的返回
    • 我不太明白你的意思,但你可以将 AsyncTask 类放在 Home (Activity) 类中。这样您就可以在 doInBackground 中访问您的 Home 类变量,并用您从 API 调用中获得的数据填充它们。
    猜你喜欢
    • 2012-06-09
    • 2010-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-03
    • 2017-06-02
    • 2010-09-07
    • 2017-12-06
    相关资源
    最近更新 更多