繁体   English   中英

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

[英]Updating One ListView From Two Different AsyncTask

我有一个具有内部 AsyncTask class 的活动 (MainActivity)。 这个 class 获取本地无线配置,例如:ip 地址、子网、网关等。我有一个外部 Asynctask 获取外部 ip 配置。 like ip address, hostname, location etc. the second class uses a json rest api for this. 但是当我从第二个 class 发布到列表视图时,我无法做到。 我不知道这是否可能。 我将当前上下文传递给第二个 class 并使用 WeakReferences 以防主要活动终止。 另外,我正在为列表视图使用自定义数组适配器。 据我了解,doinbackground() 方法在不同的线程中运行,所以这两个类之间是如何同步的。 我正在考虑的替代解决方案不是直接从第二个 class 发布到列表视图中,而是存储在 mainclass 上的变量中,然后将 output 存储到第一个异步任务的列表视图中。 但这会产生意想不到的结果。 这是怎么做的。 有没有人做过类似的事情? 谢谢 注意:我从 mainactivity 中删除了一些导入,否则 class 会在这里占用太多空间。 主要活动

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

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()
            }            
        }
    }
}

在 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