简体   繁体   English

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

[英]Updating One ListView From Two Different AsyncTask

I have an activity (MainActivity) that has an inner AsyncTask class.我有一个具有内部 AsyncTask class 的活动 (MainActivity)。 This class gets local wireless configurations like: ip address, subnet, gateway etc. I have an external Asynctask that gets external ip configuration.这个 class 获取本地无线配置,例如:ip 地址、子网、网关等。我有一个外部 Asynctask 获取外部 ip 配置。 like ip address, hostname, location etc. the second class uses a json rest api for this. like ip address, hostname, location etc. the second class uses a json rest api for this. But when I post to the listview from second class I'm not able to.但是当我从第二个 class 发布到列表视图时,我无法做到。 I don't know if this is possible.我不知道这是否可能。 I pass the current context to second class and use WeakReferences in case the main activity terminates.我将当前上下文传递给第二个 class 并使用 WeakReferences 以防主要活动终止。 Also, I'm using a custom array adapter for the listview.另外,我正在为列表视图使用自定义数组适配器。 from what I understand doinbackground() method run in different threads so how synchronization happens between these two classes.据我了解,doinbackground() 方法在不同的线程中运行,所以这两个类之间是如何同步的。 An alternate solution I was thinking instead of posting directly into the listview from second class is to store in a variable on mainclass and then output to listview from 1st asynctask.我正在考虑的替代解决方案不是直接从第二个 class 发布到列表视图中,而是存储在 mainclass 上的变量中,然后将 output 存储到第一个异步任务的列表视图中。 but that gives unexpected results.但这会产生意想不到的结果。 How is this done.这是怎么做的。 has any one done something similar before?有没有人做过类似的事情? thanks Note: I remmoved some import from mainactivity otherwise class was going to take too space here.谢谢 注意:我从 mainactivity 中删除了一些导入,否则 class 会在这里占用太多空间。 Main Activity主要活动

package org.techgeorge.netxcan;
import org.apache.commons.net.util.SubnetUtils;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import utils.IpUtils;

public class MainActivity extends AppCompatActivity {
    private ListView listView;
    private ArrayList<String> wifiIface;
    private WifiAdapter wifiAdapter;
    private String TAG = this.getClass().getName();
    private String extIpv6;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        wifiIface = new ArrayList<>();

        listView = (ListView) findViewById(R.id.output_list);
        wifiAdapter = new WifiAdapter(this, R.layout.list_item, wifiIface);
        listView.setAdapter(wifiAdapter);

        WifiAsyncTask wifiTask = new WifiAsyncTask(this);
        wifiTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

        getWanIpInfo();

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public void setExtIpv6(String ipv6) {
        this.extIpv6 = ipv6;
    }

    public ArrayList<String> getWifiIface() {
        return wifiIface;
    }

    public ArrayAdapter<String> getArrayAdapter() {
        return wifiAdapter;
    }

    public void getWanIpInfo() {
        WanIpTask wanIpTask = new WanIpTask(this);
        wanIpTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    public class WifiAsyncTask extends AsyncTask<Void, Void, Void> {
        WeakReference<MainActivity> weakReference;
        private static final String WEB_IP_SERVICE = "https://ipinfo.io/json";
        String error = "Couldn't get external IP";
        int subnet;
        Wireless wifi;

        public WifiAsyncTask(MainActivity activity) {
            weakReference = new WeakReference<>(activity);
        }

        @Override
        protected void onPreExecute() {
            wifi = new Wireless(getApplicationContext());
            wifi.getInternalMobileIpAddress();
        }

        @Override
        protected Void doInBackground(Void... params) {
            try {
                if ( wifi.getNetworkInfo() != null && wifi.getNetworkInfo().isConnected()) {
                    adding Lan stuff
                    subnet = wifi.getInternalWifiSubnet();
                    wifiIface.add("LAN Information");
                    wifiIface.add("Ipv6 "+wifi.getIpv6());
                    wifiIface.add("Mac "+wifi.getMacAddress());
                    wifiIface.add("Ipv4 "+wifi.getWifiInetAddress().getHostAddress()+"/"+subnet);
                    wifiIface.add("Host "+wifi.getWifiInetAddress().getHostName());
                    wifiIface.add("Dns1 "+IpUtils.getIpToString(wifi.getDhcpInfo().dns1));
                    wifiIface.add("Dns2 "+IpUtils.getIpToString(wifi.getDhcpInfo().dns2));
                    wifiIface.add("Gateway "+IpUtils.getIpToString(wifi.getDhcpInfo().gateway));

                    //adding wireless stuff
                    wifiIface.add("WIFI Information");
                    wifiIface.add("SSID "+wifi.getSSID());
                    wifiIface.add("Speed "+wifi.getLinkSpeed()+ "Mbs");
                    wifiIface.add("Signal "+wifi.getWifiInfo().getRssi() + "db");
                    wifiIface.add("Channel "+wifi.getWifiInfo().getNetworkId() + "");

                    }
                }
            } catch (Wireless.NoConnectivityManagerException e) {
                e.printStackTrace();
            } catch (Wireless.NoWifiManagerException e) {
                e.printStackTrace();
            } catch (SocketException e) {
                e.printStackTrace();
            } catch (Wireless.NoWifiInterface noWifiInterface) {
                noWifiInterface.printStackTrace();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Void... values) {
            wifiAdapter.notifyDataSetChanged();
        }

        @Override
        protected void onPostExecute(Void... values) {
            MainActivity activity = weakReference.get();
            if(activity != null || !activity.isFinishing()) {
                wifiAdapter.notifyDataSetChanged();
            }
        }

    }
}

WanAsynTask WanAsynTask

package org.techgeorge.netxcan;

import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.util.Log;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class WanIpTask extends AsyncTask<Void, Void, String> {

    // IP service is 100% open source https://github.com/aaronjwood/public-ip-api
//    private static final String EXTERNAL_IP_SERVICE = "https://public-ip-api.appspot.com/";
    private static final String EXTERNAL_IP_SERVICE = "https://ipinfo.io/json";
    private final WeakReference<MainActivity> delegate;

    /**
     * Constructor to set the delegate
     *
     * @param delegate Called when the external IP has been fetched
     */
    public WanIpTask(MainActivity delegate) {
        this.delegate = new WeakReference<>(delegate);
    }

    /**
     * Fetch the external IP address
     *
     * @param params
     * @return External IP address
     */
    @Override
    @SuppressLint("NewApi")
    protected String doInBackground(Void... params) {
        String error = "Couldn't get external IP";
        OkHttpClient httpClient = new OkHttpClient();
        Request request = new Request.Builder().url(EXTERNAL_IP_SERVICE).build();

        try (Response response = httpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                return error;
            }
            return response.body().string().trim();
        } catch (IOException e) {
            return error;
        }
    }

    /**
     * Calls the delegate when the external IP has been fetched
     *
     * @param result External IP address
     */
    @Override
    protected void onPostExecute(String result) {
        MainActivity activity = delegate.get();
        if (activity != null) {
            activity.getWifiIface().add(result);
            String[] wanResult = result.split("\n");
            for(int i = 0; i < wanResult.length; i++) {
                activity.getWifiIface.add()
            }            
        }
    }
}

In WanAsynTask you are not not updating adapter在 WanAsynTask 你没有更新适配器

@Override
protected void onPostExecute(String result) {
    MainActivity activity = delegate.get();
    if (activity != null) {
        activity.getWifiIface().add(result);
        String[] wanResult = result.split("\n");
        for(int i = 0; i < wanResult.length; i++) {
            activity.getWifiIface.add()
        }  
        // notify adapter    
        activity.wifiAdapter.notifyDataSetChanged();

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM