1

您好,我使用 AsyncTask 实现了一个简单的 RSS Feed 阅读器,它运行良好。我正在尝试升级我的小 APP 以使用 ASYNCTASKLOADER,以学习如何使用 Loaders。

注意上面的两行代码:

public void onCreate(Bundle savedInstanceState){

班级的RSSMain...

new getRSSFeeds().execute(); 
getLoaderManager().initLoader(0, null, callBacks1); 

通过取消/注释这两行,我决定使用哪种模式来尝试我的应用程序。当我尝试使用 getLoaderManager 阅读 RSS 提要时,我得到的只是一个空白 Activity。

附上我的代码。我的代码一定有一些概念上的错误,因为我对所有这些东西都不熟悉。有人现在如何解决它?

考虑到我 3 周前开始为 Android 编程,我的代码可能远非完美,因此欢迎提出任何改进意见!

    public class RSSMain extends ListActivity { 

    private ArrayList<rssentry> itemlist2 = null;   //LIST OF ALL RSS FEEDS
    private RSSListAdaptor2 rssadaptor2 = null;     //A SINGLE RSS POST
    private String sourceurl=null;
    public final static String EXTRA_MESSAGE = "com.example.rssjosh.MESSAGE";   //DECLARE PAYLOAD MESSAGE FOR THE ACTIVITY-CALLING INTENT
    private static final int LENGTH_SHORT = 0;
    private static final int LENGTH_LONG = 1;

    String toastxt="empty...";
    Toast toast; 


    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);

        //LoaderManager lmanager = getLoaderManager().initLoader(0, null, new RSSLoaderCallback, getBaseContext());
        //getLoaderManager().initLoader(0, savedInstanceState, new RSSLoader(null));
        sourceurl="http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest";
        itemlist2 = new ArrayList<rssentry>();      

       getLoaderManager().initLoader(0, null, callBacks1);  //CREATES AND INITS. LOADER (ASYNCTASKLOADER MODE)
     //new getRSSFeeds().execute();  

    }    
@Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
            super.onListItemClick(l, v, position, id);
            String s=null;                                
            rssentry data = itemlist2.get(position);    //GET THE RSSENTRY THAT WAS TOUCHED BY THE USER            
            //TEMPORARY TOAST TO CHECK CORRECT STRING FORMATION
            //String toastxt="XD!";
            //int duration = Toast.LENGTH_LONG;            //toastxt=toastxt+data.title+"\n"+data.published+"\n"+data.link+"\n"+data.summary.substring(30,140)+"\n";    
            //FORM THE HTML TEXT TO BE SENT TO THE SIGLE-RSSFEED DISPLAY ACTIVITY
            StringBuilder htmlString = new StringBuilder();
            htmlString.append(data.title+"$");
            htmlString.append("Published on: "+data.published+"$");  
            htmlString.append(data.summary+"$");        
            htmlString.append("URL: "+data.link+"$");

            Intent intent = new Intent(this,Rssactivity.class); 
            //LOADS THE INTENT WITH THE <HTML> PAYLOAD          
            intent.putExtra(EXTRA_MESSAGE, htmlString.toString());  ///public final static String EXTRA_MESSAGE = "com.example.rssjosh.MESSAGE"; DECLARED ABOVE         
            startActivity(intent);       //LAUNCHES INTENT
    }
//SERVICE METHOD TO private String retrieveRSSFeed2(String urlToRssFeed)
// _URLstring -> INPUT_STREAM
 private InputStream downloadUrl(String urlString) throws IOException {
     URL url = new URL(urlString);
     HttpURLConnection conn = (HttpURLConnection) url.openConnection();
     conn.setReadTimeout(10000 /* milliseconds */);
     conn.setConnectTimeout(15000 /* milliseconds */);
     conn.setRequestMethod("GET");
     conn.setDoInput(true);
     // STARTS QUERYING THE STREAM
     conn.connect();
     InputStream stream = conn.getInputStream();
     return stream;
 }
//URL -> (INPUT_STREAM) -> List<rssentry> entries 
//THIS VARIANT OF THE RETRIEVERSSFEED2 METHOD, RETURNS RESULT IN A STRING FORMAT (OPTIONAL METHOD)
    private ArrayList<rssentry> retrieveRSSFeed2Str(String urlToRssFeed) throws XmlPullParserException, IOException
        {       
        ArrayList<rssentry> itemlist = new ArrayList<rssentry>();
        //INSTANTIATES A NEW PARSER "parsero", AND AN EMPTY RSSENTRY ARRAYLIST
        InputStream stream = null;
        //List<rssentry> entries = null; UPGRADED TO PUBLIC CLASS ATTRIBUTE
        xmlparser parsero = new xmlparser();
        //This Try does URL->Stream
    try {
        stream = downloadUrl(urlToRssFeed);     //OBTAIN A CHARACTER STREAM FROM THE rssURL     
        itemlist = parsero.parse(stream);       //PARSE STREAM AND STORE rssENTRIES IN THE "ENTRIES" ARRAYLIST <rssentry>        
    } finally {
        if (stream != null) {
            stream.close();                     //CLOSE STREAM AFTER USING IT
        }
    }

    return itemlist;

}
  //GETS RSS FEED IN ASYNCHRONOUS MODE
   class ATLgetfeeds extends AsyncTaskLoader <ArrayList<rssentry>>{ 
        private ArrayList<rssentry> rsslist=null;
        private ProgressDialog progress = null;

        public ATLgetfeeds(Context context) {
            super(context);
            }

        @Override
        protected void onStartLoading() {
            if (rsslist != null) 
              deliverResult(rsslist); // Use the cache
            else
                forceLoad();
            }

        @Override
        public ArrayList<rssentry> loadInBackground() {
            try {                   
                itemlist2 = null; //<=THIS LIST IS TO BE LOADED WITH THE RSS URL BELOW
                rsslist = retrieveRSSFeed2Str("http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest");  //SETS ITEMLIST2
                } catch (XmlPullParserException e) {
                e.printStackTrace();
            } catch (IOException e) {
                    e.printStackTrace();
                    }           
                //LOADS DATA INTO RSSADAPTER (PARSER2)
            rssadaptor2 = new RSSListAdaptor2(RSSMain.this, R.layout.rssitemview,rsslist);
            return null;
            }   

        @Override
        public void deliverResult(ArrayList<rssentry> data) {
            rsslist = data; // Caching
            super.deliverResult(data);
        }

        @Override
        protected void onReset() {
           super.onReset();
           // Stop the loader if it is currently running
           onStopLoading();
           rsslist = null;
        }

        @Override
        public void onCanceled(ArrayList<rssentry> data) {
           // Attempt to cancel the current async load
           super.onCanceled(data);
           rsslist = null;
       }        

        protected void onPreExecute() {
            progress = ProgressDialog.show( RSSMain.this, null, "RSSJosh Loading..."); //LOADING MESSAGE
            //   super.onPreExecute();
            }


        protected void onPostExecute(Void result) {
            itemlist2=rsslist;
            setListAdapter(rssadaptor2);
            progress.dismiss(); //Dismisses loading progress dialog                     
              //s super.onPostExecute(result);
           }                                                 
    }   
    //GETS RSS FEED IN ASYNCHRONOUS MODE
    private class getRSSFeeds extends AsyncTask<Void, Void, Void>
    {   
    private ProgressDialog progress = null;
    ArrayList<rssentry> atlist = new ArrayList<rssentry>();
            @Override
            protected Void doInBackground(Void... params) {
                try {
                    itemlist2 = null; //<=THIS LIST IS TO BE LOADED WITH THE RSS URL BELOW                  
                    atlist = retrieveRSSFeed2Str("http://stackoverflow.com/feeds/tag?tagnames=android&sort=newest");
                } catch (XmlPullParserException e) {                    
                    e.printStackTrace();  // TODO Auto-generated catch block
                } catch (IOException e) {                   
                    e.printStackTrace(); // TODO Auto-generated catch block
                }

                //LOADS DATA INTO UI RSSADAPTER (PARSER2)
                rssadaptor2 = new RSSListAdaptor2(RSSMain.this, R.layout.rssitemview,atlist);
                return null;
            }

            @Override
            protected void onCancelled() {
                    super.onCancelled();
            }

            @Override
            protected void onPreExecute() {
                    progress = ProgressDialog.show( RSSMain.this, null, "RSSJosh Loading..."); //LOADING MESSAGE
                    super.onPreExecute();
            }

            @Override
            protected void onPostExecute(Void result) {
                    setListAdapter(rssadaptor2);
                    itemlist2=atlist;
                    progress.dismiss(); //Dismisses loading progress dialog                     
                    super.onPostExecute(result);
            }

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

    //RSS ADAPTER (TYPE2) FOR STACK-OVERFLOW RSSFEEDS
    private class RSSListAdaptor2 extends ArrayAdapter<rssentry>{
    private List<rssentry> objects = null;

            public RSSListAdaptor2(Context context, int textviewid, List<rssentry> objects) {
                    super(context, textviewid, objects);                     
                    this.objects = objects;
            }

            @Override
            public int getCount() {
                    return ((null != objects) ? objects.size() : 0);
            }

            @Override
            public long getItemId(int position) {
                    return position;
            }

            @Override
            public rssentry getItem(int position) {
                    return ((null != objects) ? objects.get(position) : null);
            }

            public View getView(int position, View convertView, ViewGroup parent) {
                    View view = convertView;

                    if(null == view)
                    {
                            LayoutInflater vi = (LayoutInflater)RSSMain.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                            view = vi.inflate(R.layout.rssitemview, null);
                    }

                    rssentry data = objects.get(position);

                    if(null != data)
                    {       //CREATE TEXTVIEW OBJECTS FORTITLE, DATE AND DESCRIPTION DATA
                            TextView title = (TextView)view.findViewById(R.id.txtTitle);
                            TextView date = (TextView)view.findViewById(R.id.txtDate);                            
                            TextView description = (TextView)view.findViewById(R.id.txtDescription);

                            //PUT TEXT ON TITLE AND DATE VIEWS
                            title.setText(data.title);
                            date.setText("Published on: " + data.published); //PREVIOUSLY date.setText("on " + data.date);

                            //PREPARE AND LOAD TEXT FOR THE SUMMARY VIEW
                            String txt=null;
                            //Clean and trim summary string before displaying
                            txt=data.summary.toString().substring(30,data.summary.toString().length());
                            if (txt.length()>=300)
                                txt=txt.substring(0,299)+"..."; ///DISPLAY A SUMMARY OF 300 CHARACTERS MAX, IN THE RSS HEADLINES                            
                            description.setText(txt); //PUT TEXT
                    }

                    return view;
            }
}



    LoaderManager.LoaderCallbacks<ArrayList<rssentry>> callBacks1 = new                  LoaderManager.LoaderCallbacks<ArrayList<rssentry>>() {
/* Implement the three callback methods here */

    public android.content.Loader<ArrayList<rssentry>> onCreateLoader( //START LOADING
            int arg0, Bundle arg1) {
        // TODO Auto-generated method stub
        android.content.Loader<ArrayList<rssentry>> rsslist=null;

        //TEMPORARY TOAST TO DEBUG CORRECT STRING FORMATION      
        toastxt="Toastiee! Preparing for ATL Task";
        toast = Toast.makeText(getBaseContext(), toastxt, LENGTH_SHORT);
        toast.show();

        ATLgetfeeds a= new ATLgetfeeds(getBaseContext());

      //TEMPORARY TOAST TO DEBUG CORRECT STRING FORMATION  
        toastxt="Toastiee! ATL Task created";
        toast = Toast.makeText(getBaseContext(), toastxt, LENGTH_SHORT);
        toast.show();

        return rsslist;
    }

    @Override
    public void onLoadFinished(  //START LOADING
            android.content.Loader<ArrayList<rssentry>> arg0,
            ArrayList<rssentry> arg1) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onLoaderReset(android.content.Loader<ArrayList<rssentry>> arg0) {
        // TODO Auto-generated method stub      
    }   
};
}
4

0 回答 0