从 Asynctask 更新 MainActivity 上的 ListView

Posted

技术标签:

【中文标题】从 Asynctask 更新 MainActivity 上的 ListView【英文标题】:Updating a ListView on MainActivity from Asynctask 【发布时间】:2017-08-04 01:39:43 【问题描述】:

我在主 UI 上有一个列表视图,我希望通过连接到 Mikrotik 设备以检索详细信息的 Asynctask 更新它。

我也在传递活动,以便我可以从单独的类文件更新 UI,但是在 ListAdapter 构造函数中,活动 (mActivity) 不断收到错误“此处预期的类名”。

这里是异步任务代码:

public class MikrotikReader extends AsyncTask<String, Void, ArrayList<String>> 

    //Default connection details for mikrotik
    private int mkPort = 8728;
    private int mkTimeout = 5000;
    private String userName;
    private String userPass;
    private String mkIpAddress;
    private String mkCommand;
    private ListView listView;
    private Activity mActivity;

    public MikrotikReader(String user, String pass, String ipaddress, String command, Activity activity) 
        this.userName = user;
        this.userPass = pass;
        this.mkIpAddress = ipaddress;
        this.mkCommand = command;
        this.mActivity = activity;
    



    @Override
    protected ArrayList<String> doInBackground(String... params) 


        ArrayList<String> mylist = new ArrayList<String>();

        try 
            ApiConnection con = ApiConnection.connect(SocketFactory.getDefault(), mkIpAddress, mkPort, mkTimeout);
            con.login(userName, userPass); // log in to router
            if (con.isConnected()) 
                List<Map<String, String>> rs1 = con.execute(mkCommand);
                for (Map<String, String> results1 : rs1) 
                    getResults[0] = new String(results1.get("comment"));
                    mylist.add(getResults[0]);
                
                con.close();
            
         catch (MikrotikApiException e) 
         catch (Throwable e) 
            e.printStackTrace();
        
        return mylist;
    

@Override
    protected void onPostExecute(ArrayList<String> mylist) 

        System.out.println("This is the array content " + mylist.get(0));

        listView = (ListView) mActivity.this.findViewById(R.id.listView);
        listView.setAdapter(new ArrayAdapter<String>(mActivity.this,android.R.layout.simple_list_item_1,new ArrayList<String>())); 

这就是我从 MainActivity 类文件中调用 Asynctask 的方式,将“this”作为活动传递:

new MikrotikReader(user_name, password, ipaddress,"/ip/firewall/filter/print where comment=Test", this).execute();

这是 mainactivity.xml 文件中的列表视图:

<ListView
        android:id="@+id/listView"
        android:layout_
        android:layout_
        android:background="@drawable/gradient_bg" />

【问题讨论】:

这不是在另一个活动中更新列表视图的正确方法。不要将此异步任务放在不同的类中。您可以使用接口或简单地将其放在同一个类中。然后你不需要通过Activity。 有人告诉我,最好的做法是拥有单独的可重用类文件,维护面向对象的代码,并在它们之间传递数据。由于我有其他类文件处理异步任务以检索或将数据写入 Mikrotik 设备,你是否建议我在同一个类文件中实现它们?这将导致一个大块的 main_activity 文件。这是推荐的方式吗? 【参考方案1】:

尝试在你的 AsyncTask 类中只使用 mActivity 而不是 mActivity.this

【讨论】:

【参考方案2】:

不要这样做。 使界面像

    public interface ListPreparingListener 
void onListPrepared(ArrayList<String> mylist);

并在您的主要活动中实施它,例如

@Override
onListPrepared(ArrayList<String> myList) 
 listView.setAdapter(new ArrayAdapter<String>(mActivity.this,android.R.layout.simple_list_item_1,new ArrayList<String>()));

然后,将此接口传递给读者的构造函数,并在执行后调用此方法

更新: 实际上,如果您将对您的活动的引用存储在其他对象中,它可能会产生内存泄漏。最合适的方法是创建方法subscribeListenerunsubsucribeListener 并在需要时从主活动订阅,取消订阅onStop。还应在您的 onPostExecute 上检查是否有可用的侦听器

【讨论】:

以上是关于从 Asynctask 更新 MainActivity 上的 ListView的主要内容,如果未能解决你的问题,请参考以下文章

从两个不同的 AsyncTask 更新一个 ListView

从 AsyncTask 更新视图

重新创建活动时如何从 AsyncTask 更新 TextView

从 AsyncTask 滞后 UI 更新 ProgressBar

从 AsyncTask 更新 Activity 中的进度对话框

在 Android 中,如何从 AsyncTask 更改 TextView? [复制]