【问题标题】:AsyncTask doInbackground returns arraylist value but in onPostExecute arraylist is 0AsyncTask doInbackground 返回 arraylist 值,但在 onPostExecute arraylist 为 0
【发布时间】:2025-12-02 08:45:01
【问题描述】:

在 Asynctask doInBackground 我从 firebase 数据库获取 arraylist 并返回 arraylist(return 30 maps) 结果,但在 onPostExecute arraylist 为 0(不保留在做背景)。我认为问题 - doInBackground 像并行线程一样工作。好的。 我还尝试将 doInbackground 中的数据插入到 onCreate 但它也不起作用(返回 arraylist 0)。 那是我的代码。我的代码有什么问题?

  public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.listview_main);
        ParseTitle parseTitle = new ParseTitle();
        parseTitle.execute();
    }
public class ParseTitle extends AsyncTask<Void, Void, ArrayList<HashMap<String, String>>> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        avLoadingIndicatorView = (com.wang.avi.AVLoadingIndicatorView) findViewById(R.id.avi);
        avLoadingIndicatorView.show();
    }

    @Override
    protected ArrayList<HashMap<String, String>> doInBackground(Void... params) {
        arraylist = new ArrayList<HashMap<String, String>>();
        database = FirebaseDatabase.getInstance();
        ref1 = database.getReference("work");
        ref = ref1.child("worker");
        ref.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot ds : dataSnapshot.getChildren()) {
                    String s_position = (String) ds.child("v_position").getValue();
                    String s_employer = (String) ds.child("v_company").getValue();
                    String s_posted = (String) ds.child("v_post").getValue();
                    String s_link = (String) ds.child("v_url").getValue();

                    HashMap<String, String> map = new HashMap<String, String>();
                    map.put("POSITION", s_position);
                    map.put("EMPLOYER", s_employer);
                    map.put("POSTED", s_posted);
                    map.put("LINK", s_link);
                    map.put("TYPE", "IT");
                    arraylist.add(map);
                }

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
               // System.out.println("The read failed: " + DatabaseError.DATA_STALE);
            }
        });
        return  arraylist;
    }
    @Override
    protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
        listView = (ListView) findViewById(R.id.listview);
      //  Collections.sort(arraylist,SortByValue);
        //HashMap<String, Integer> sortedMap = (HashMap<String, Integer>) sortByValue(arraylist);
       // if(arraylist != null && arraylist.size() > 0) {
            adapter = new ListViewAdapter(IT.this, arraylist);
            listView.setAdapter(adapter);
            avLoadingIndicatorView.hide();
            findViewById(android.R.id.content).setBackgroundColor(Color.TRANSPARENT);
      //  }
    }
}

如果有人帮我解决上面指定的问题,那就太好了。 :)

【问题讨论】:

  • 你在哪里声明arraylist?在任何情况下,onPostExecute 只会在异步任务完成之后由 Android 调用,这是有保证的。因此,您对它尚未完成的担忧并不是真正的 AFAIK。
  • 对不起,伙计,在 onPreExcute 中初始化您的数组列表并检查...
  • @SuryanarayanaReddy 怎么做?可以展示一下吗?
  • @TimBiegeleisen Arraylist 在 doInBackground 中声明。
  • 不,不是。您在后台任务中初始化它,但您当然不会在那里声明它。你在哪里声明?

标签: java android arrays arraylist android-asynctask


【解决方案1】:

不需要整个AsyncTask,因为FirebaseDatabase 事件被称为异步事件。您的doInBackground 运行得非常快,并且在您收到onDataChange 的结果之前调用了onPostExecute。 如果没有AsyncTask,它可能看起来像这样:

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.listview_main);
        ParseTitle parseTitle = new ParseTitle();
        parseTitle.execute();
avLoadingIndicatorView = (com.wang.avi.AVLoadingIndicatorView) findViewById(R.id.avi);
avLoadingIndicatorView.show();
arraylist = new ArrayList<HashMap<String, String>>();
database = FirebaseDatabase.getInstance();
ref1 = database.getReference("vacancies");
ref = ref1.child("jobsearch");
ref.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot ds : dataSnapshot.getChildren()) {
            String s_position = (String) ds.child("v_position").getValue();
            String s_employer = (String) ds.child("v_company").getValue();
            String s_posted = (String) ds.child("v_post").getValue();
            String s_link = (String) ds.child("v_url").getValue();

            HashMap<String, String> map = new HashMap<String, String>();
            map.put("POSITION", s_position);
            map.put("EMPLOYER", s_employer);
            map.put("POSTED", s_posted);
            map.put("LINK", s_link);
            map.put("TYPE", "IT");
            arraylist.add(map);
        }
        adapter = new ListViewAdapter(IT.this, arraylist);
        listView.setAdapter(adapter);
        avLoadingIndicatorView.hide();
        findViewById(android.R.id.content).setBackgroundColor(Color.TRANSPARENT);

    }
}

【讨论】:

  • 感谢您的帮助。我按照您的建议进行了检查,并且有效。但是有 1-2 秒的等待时间。好吧,这并不难看。非常感谢。
【解决方案2】:

替换:

adapter = new ListViewAdapter(IT.this, arraylist);

adapter = new ListViewAdapter(IT.this, result);

【讨论】:

  • İ 只是检查你写的,但结果大小也是 0。
  • 这可能不是必需的,假设arrayList 定义在onPostExecute 也可见的范围内。
  • 需要在构造函数中初始化arrayList,在doInBackground()之外;
  • 我删除了arraylist = new ArrayList>();从 doInbackground 但现在 arraylist 返回 null。那不行……
  • 为 ParseTitle 类创建构造函数。在那里初始化 arryList