Using AsyncTask with passing a value

前端 未结 1 1819
眼角桃花
眼角桃花 2020-11-28 16:25

I have been working on this and I have hit a point where I dont know what to do. What I am trying to do is use one class to download and parse out a file into a string and t

相关标签:
1条回答
  • 2020-11-28 16:46

    Alright, here is a pretty flexible pattern for the overall usage of using AsyncTask to download web content and getting the results from it back to the UI thread.

    Step 1 Define an interface that will act as a message bus between the AsyncTask and where you want the data.

    public interface AsyncResponse<T> {
        void onResponse(T response);
    }
    

    Step 2 Create a generic AsyncTask extension that will take any URL and return the results from it. You basically had this already, but I made some tweaks. Most importantly, allowing the setting of the AsyncResponse callback interface.

    public class WebDownloadTask extends AsyncTask<String, Void, String> {
    
        private AsyncResponse<String> callback;
    
        // Optional parameters
        private String username;
        private String password;
    
        // Make a constuctor to store the parameters
        public WebDownloadTask(String username, String password) {
            this.username = username;
            this.password = password;
        }
    
        // Don't forget to call this
        public void setCallback(AsyncResponse<String> callback) {
            this.callback = callback;
        }
    
        @Override
        protected String doInBackground(String... params) {
            String url = params[0];
            return readFromFile(url);
        }
    
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            if (callback != null) {
                callback.onResponse(s);
            } else {
                Log.w(WebDownloadTask.class.getSimpleName(), "The response was ignored");
            }
        }
    
        /******* private helper methods *******/
    
        private String streamToString(InputStream is) throws IOException {
    
            StringBuilder sb = new StringBuilder();
            BufferedReader rd = new BufferedReader(new InputStreamReader(is));
            String line;
            while ((line = rd.readLine()) != null) {
                sb.append(line);
            }
            return sb.toString();
        }
    
        private String readFromFile(String myWebpage) {
    
            String response = null;
            HttpURLConnection urlConnection = null;
    
            try {
                //Get the url connection
                URL url = new URL(myWebpage);
    
                // Unnecessary for general AsyncTask usage
                /* 
                Authenticator.setDefault(new Authenticator() {
                    @Override
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(username, password.toCharArray());
                    }
                });
                */
    
                urlConnection = (HttpURLConnection) url.openConnection();
    
                InputStream inputStream = urlConnection.getInputStream();
    
                if (inputStream != null) {
                    response = streamToString(inputStream);
                    inputStream.close();
                    Log.d("Final String", response);
                }
    
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (urlConnection != null) {
                    urlConnection.disconnect();
                }
            }
    
            return response;
        }
    }
    

    Step 3 Go forth and use that AsyncTask wherever you wish. Here is an example. Note that if you do not use setCallback, you will be unable to get the data that came from the AsyncTask.

    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            WebDownloadTask task = new WebDownloadTask("username", "password");
            task.setCallback(new AsyncResponse<String>() {
                @Override
                public void onResponse(String response) {
                    // Handle response here. E.g. parse into a JSON object
                    // Then put objects into some list, then place into an adapter... 
                    Toast.makeText(getApplicationContext(), response, Toast.LENGTH_SHORT).show();
                }
            });
    
            // Use any URL, this one returns a list of 10 users in JSON
            task.execute("http://jsonplaceholder.typicode.com/users");
        }
    }
    
    0 讨论(0)
提交回复
热议问题