0

我的演示程序有一些問題。我創建了一個工作正常的新聞閱讀器應用程序。這個應用程序正在使用黑客新聞API下載新聞。Android:ProgressBar不能正常工作或顯示

當我試圖添加ProgressBar時,直到我的ListView加載,不幸的是它失敗了。它不工作,甚至沒有顯示。

我已經發布了所有我的工作應用程序,但是,只有MainActivity.java和activity_main.xml需要審查。

我盡力找到答案但徒勞無功。請幫我查看我的問題。以下是我的代碼。在此先感謝所有願意幫助的人。

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?> 
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.xpertwireless.newsreader.MainActivity"> 

    <ListView 
     android:id="@+id/listView" 
     android:layout_width="0dp" 
     android:layout_height="0dp" 
     app:layout_constraintBottom_toBottomOf="parent" 
     app:layout_constraintHorizontal_bias="0.0" 
     app:layout_constraintLeft_toLeftOf="parent" 
     app:layout_constraintRight_toRightOf="parent" 
     app:layout_constraintTop_toTopOf="parent" 
     app:layout_constraintVertical_bias="1.0" 
     tools:layout_constraintBottom_creator="1" 
     tools:layout_constraintLeft_creator="1" 
     tools:layout_constraintRight_creator="1" 
     tools:layout_constraintTop_creator="1" /> 

    <ProgressBar 
     android:id="@+id/progressBar" 
     style="?android:attr/progressBarStyle" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginBottom="8dp" 
     android:layout_marginTop="8dp" 
     android:indeterminate="true" 
     android:visibility="visible" 
     app:layout_constraintBottom_toBottomOf="@+id/listView" 
     app:layout_constraintTop_toTopOf="@+id/listView" 
     tools:layout_editor_absoluteX="168dp" 
     tools:visibility="visible" /> 


</android.support.constraint.ConstraintLayout> 

MainActivity.java

public class MainActivity extends AppCompatActivity { 

    ListView listView; 
    ArrayList<String> newsTitle; 
    ArrayAdapter<String> arrayAdapter; 
    SQLiteDatabase newsReaderDB; 
    ProgressBar progressBar; 

    public void initializeVar() 
    { 
     progressBar = (ProgressBar) findViewById(R.id.progressBar); 

     listView = (ListView) findViewById(R.id.listView); 
     newsTitle = new ArrayList<>(); 

     newsTitle.clear(); 

     // initializing the ArrayList and Attaching it to the adapter 
     arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, newsTitle); 

     // attached 
     listView.setAdapter(arrayAdapter); // setting the adapter 


    } 

    // Setting up the DownloadTask extending AsyncTask class 
    // Which will download the data in the background 
    // in this case, JSON data 

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



     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 

      Toast.makeText(getApplicationContext(),"PRE-EXEC Working", Toast.LENGTH_SHORT).show(); 
      progressBar.setVisibility(View.VISIBLE); 

     } 

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

      Toast.makeText(getApplicationContext(),"ON-PROGRESS Working", Toast.LENGTH_SHORT).show(); 
      progressBar.setVisibility(View.VISIBLE); 

     } 

     @Override 
     protected void onPostExecute(String s) { 
      super.onPreExecute(); 

      Toast.makeText(getApplicationContext(),"POST-EXEC Working", Toast.LENGTH_SHORT).show(); 
      progressBar.setVisibility(View.GONE); 

     } 

     // Setting up the method which will execute in the background 
     // "varargs" (params ...) in below method is actually alternate way of saying that 
     // method will accept the particular type of arguments as an array 
     // in this case, array of String, which will contain urls 

     @Override 
     protected String doInBackground(String... urls) { 

      URL url; // Declaring the URL variable 
      HttpURLConnection httpURLConnection = null; // declaring and initializing the HttpURLConnection var 
      InputStream inputStream; // declaring the InputStream reader var, which will hold the incoming data stream 
      InputStreamReader inputStreamReader; // declaring and initializing the InputStreamReader var to read the incoming stream 
      int data; // this variable will actually hold the data 
      String result = ""; // this var will combine all the incoming data in the string and will be returned 

      try { 

       url = new URL(urls[0]); // initializing the URL var with the supplied url 
       httpURLConnection = (HttpURLConnection) url.openConnection(); //opening up the connection to that url 
       inputStream = httpURLConnection.getInputStream(); // getting the data using the above connection 
       inputStreamReader = new InputStreamReader(inputStream); // attaching the reader to the data 

       data = inputStreamReader.read(); // reading data, character by character 

       while (data != -1) // data will only be -1 when all the received data is read and reading cursor is at EOF 
       { 
        char current = (char) data; // this var will hold each character previously retrieved 
        result += current; // appending the read char to the final var 
        data = inputStreamReader.read(); // reading the next character 

       } 

      } catch (MalformedURLException e) { 

       e.printStackTrace(); 

      } catch (IOException e) { 

       e.printStackTrace(); 

      } 


      return result; // returning the final result 
     } 
    } 

    // This method will download the IDs for top 500 news 
    public void getNewsID() 
    { 
     String rawData = ""; 

     DownloadTask downloader = new DownloadTask(); 

     try { 

      // this will download the JSON data for news IDs (only top 500 stories will be downloaded) 

      rawData = downloader.execute("https://hacker-news.firebaseio.com/v0/topstories.json").get(); 

     } catch (InterruptedException e) { 

      e.printStackTrace(); 

     } catch (ExecutionException e) { 

      e.printStackTrace(); 

     } 


     parseNewsID(rawData); 
    } 

    // This method will extract individual news ID from the JSON Array received 

    public void parseNewsID(String rawData){ 


     try { 

      JSONArray jsonArray = new JSONArray(rawData); 

      for(int i = 0; i < jsonArray.length(); ++i) 
      { 

       int newsID = jsonArray.getInt(i); 

       if (!isNewsExist(newsID)) { // check if news ID exist in the db 

        getNewsJSON(newsID); 

       } 

      } 

     } catch (JSONException e) { 

      e.printStackTrace(); 

     } 


    } 

    // This method will get the JSON of individual news based on its ID 
    public void getNewsJSON(int newsID) 
    { 

     String newsJSON = ""; 

     DownloadTask downloadTask = new DownloadTask(); 

     try { 

      newsJSON = downloadTask.execute("https://hacker-news.firebaseio.com/v0/item/" + newsID + ".json").get(); 

     } catch (InterruptedException e) { 

      e.printStackTrace(); 

     } catch (ExecutionException e) { 

      e.printStackTrace(); 

     } 

     parseNews(newsJSON); 
    } 

    // This method will return the individual news JSON object 

    public void parseNews(String newsJSON) 
    { 
     JSONObject jsonObject = null; 

     try { 

      jsonObject = new JSONObject(newsJSON); 

     } catch (JSONException e) { 

      e.printStackTrace(); 

     } 

     downloadNewsInfo(jsonObject); 

    } 


    // This method will download the News ID, Title and URL as a string 
    public void downloadNewsInfo(JSONObject jsonObject) 
    { 
     int newsID = 0; 
     String newsTitle = ""; 
     String newsURL = ""; 

     try { 

      if (!jsonObject.isNull("title") && !jsonObject.isNull("url")) { // check if title and url exist in url 

       newsID = jsonObject.getInt("id"); 
       newsTitle = jsonObject.getString("title"); 
       newsURL = jsonObject.getString("url"); 

      } 

     } catch (JSONException e) { 

      e.printStackTrace(); 

     } 

     if (newsID != 0) { 

      insertNewsIntoDB(newsID, newsTitle, newsURL); 

     } 
    } 

    public void retrieveAndDisplayTile() 
    { 

     Cursor newsCursor = newsReaderDB.rawQuery("SELECT title FROM news", null); 
     int titleIndex = newsCursor.getColumnIndex("title"); 
     newsCursor.moveToFirst(); 

     if (newsCursor.moveToFirst()) 
     { 
      newsTitle.add(newsCursor.getString(titleIndex)); 
     } 

     while (newsCursor.moveToNext()) 
     { 

      newsTitle.add(newsCursor.getString(titleIndex)); 
      newsCursor.moveToNext(); 

     } 

     updateListView(); 
    } 

    // this method will retrieve the url corresponding to the newsTitle 
    public String retrieveURL(String newsTitle) 
    { 
     String newsURL = ""; 

     Cursor urlCursor = newsReaderDB.rawQuery("SELECT url FROM news WHERE title = '" + newsTitle + "' ",null); 
     int urlIndex = urlCursor.getColumnIndex("url"); 
     urlCursor.moveToFirst(); 

     if (urlCursor.moveToFirst()) 
     { 

      try { 

       newsURL = (String) ObjectSerializer.deserialize(urlCursor.getString(urlIndex)); 

      } catch (IOException e) { 

       e.printStackTrace(); 

      } 

     } 


     return newsURL; 
    } 

    // Check in the database if the news exist 
    public boolean isNewsExist(int newsID) 
    { 
     Cursor c = newsReaderDB.rawQuery("SELECT id FROM news", null); // start the cursor 
     int idIndex = c.getColumnIndex("id"); // get column index 
     c.moveToFirst(); // move cursor to the first entry 

     if (c.moveToFirst()) 
     { 
      if (newsID == c.getInt(idIndex)) // check if newsID is match with the ID in db 
      { 
       return true; // return true if yes 
      } 
     } 

     while (c.moveToNext()) 
     { 
      if (newsID == c.getInt(idIndex)) // check if newsID is match with the ID in db 
      { 
       return true; // return true if yes 
      } 

      c.moveToNext(); // if not, check remaining 
     } 

     return false; // return false if newsID doesn't exist in the db 
    } 

    // This method will update the ArrayAdapter, hence updating ListView with new data 
    public void updateListView() 
    { 

     arrayAdapter.notifyDataSetChanged(); 

    } 

    // This method will check if internet is available or not 
    private boolean isInternetAvailable() { 

     ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 

     NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); 

     return activeNetworkInfo != null && activeNetworkInfo.isConnectedOrConnecting(); 

    } 



    // This method will either create or open the db for this app 
    public void createOpenDB() 
    { 
     newsReaderDB = this.openOrCreateDatabase("newsReader", MODE_PRIVATE, null); 

    } 

    // This method will insert the downloaded news into the db 
    public void insertNewsIntoDB(int newsID, String newsTitle, String newsURL) 
    { 
     try { 

      String tempUrlStringObj = ObjectSerializer.serialize(newsURL); // This object serialization of the content will help save the data in the db properly and without any errors 

      String sqlStatment = "INSERT INTO news (id, title, url) VALUES (?, ? , ?)"; 

      SQLiteStatement statement = newsReaderDB.compileStatement(sqlStatment); 

      statement.bindString(1, String.valueOf(newsID)); 
      statement.bindString(2, newsTitle); 
      statement.bindString(3, tempUrlStringObj); 

      statement.execute(); 


     } catch (Exception e) 
     { 
      e.printStackTrace(); 

     } 
    } 

    // Create Table 
    public void createDBTbl() 
    { 

     newsReaderDB.execSQL("CREATE TABLE IF NOT EXISTS news (id INT(100000) PRIMARY KEY, title VARCHAR, url VARCHAR)"); 

    } 

    // Delete the table 
    public void deleteDBTbl() 
    { 
     if (isInternetAvailable()) { 

      newsReaderDB.execSQL("DROP TABLE IF EXISTS news"); 

     } 
    } 

    // This method will start the program 
    public void fireUp() 
    { 
     createOpenDB(); 
     deleteDBTbl(); 
     createDBTbl(); 
     getNewsID(); 
     retrieveAndDisplayTile(); 

    } 




    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 


     initializeVar(); // calling the variable initializer fnx 
     fireUp(); // Start the app 

     Toast.makeText(getApplicationContext(),"Total number of news items are: " + listView.getAdapter().getCount(),Toast.LENGTH_LONG).show(); 

     // Setting the onClickListener for ListView 
     listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 

      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 

       String title = (String)listView.getItemAtPosition(position); 
       String url = retrieveURL(title); 

       // Send URL to the webView Activity 
       Intent intent = new Intent(getApplicationContext(), Main2Activity.class); 
       intent.putExtra("URL", url); 
       startActivity(intent); 
      } 
     }); 



    } 
} 

activity_main2.xml

<?xml version="1.0" encoding="utf-8"?> 
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.xpertwireless.newsreader.Main2Activity"> 

    <WebView 
     android:id="@+id/webView" 
     android:layout_width="368dp" 
     android:layout_height="495dp" 
     android:paddingBottom="0dp" 
     android:paddingEnd="0dp" 
     android:paddingLeft="0dp" 
     android:paddingRight="0dp" 
     android:paddingStart="0dp" 
     android:paddingTop="0dp" 
     tools:layout_editor_absoluteX="8dp" 
     tools:layout_editor_absoluteY="8dp" /> 
</android.support.constraint.ConstraintLayout> 

Main2Activity.java

public class Main2Activity extends AppCompatActivity { 

    String newsURL = ""; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main2); 

     WebView webView = (WebView) findViewById(R.id.webView); 
     webView.getSettings().setJavaScriptEnabled(true); // setting javascript enabled 
     webView.setWebViewClient(new WebViewClient()); // open the web page in the same application 

     newsURL = getIntent().getStringExtra("URL"); // getting url through intent 

     webView.loadUrl(newsURL); // loading url 

    } 
} 

ObjectSerializer.java

public class ObjectSerializer { 


    public static String serialize(Serializable obj) throws IOException { 

     if (obj == null) return ""; 

     try { 

      ByteArrayOutputStream serialObj = new ByteArrayOutputStream(); 
      ObjectOutputStream objStream = new ObjectOutputStream(serialObj); 
      objStream.writeObject(obj); 
      objStream.close(); 
      return encodeBytes(serialObj.toByteArray()); 

     } catch (Exception e) { 

      throw new RuntimeException(e); 
     } 
    } 

    public static Object deserialize(String str) throws IOException { 

     if (str == null || str.length() == 0) 
     { 
      return null; 
     } 

     try { 

      ByteArrayInputStream serialObj = new ByteArrayInputStream(decodeBytes(str)); 
      ObjectInputStream objStream = new ObjectInputStream(serialObj); 
      return objStream.readObject(); 

     } catch (Exception e) { 

      throw new RuntimeException(e); 

     } 
    } 

    public static String encodeBytes(byte[] bytes) { 

     StringBuffer strBuf = new StringBuffer(); 

     for (int i = 0; i < bytes.length; i++) { 

      strBuf.append((char) (((bytes[i] >> 4) & 0xF) + ((int) 'a'))); 
      strBuf.append((char) (((bytes[i]) & 0xF) + ((int) 'a'))); 

     } 

     return strBuf.toString(); 
    } 

    public static byte[] decodeBytes(String str) { 

     byte[] bytes = new byte[str.length()/2]; 

     for (int i = 0; i < str.length(); i += 2) { 
      char c = str.charAt(i); 
      bytes[i/2] = (byte) ((c - 'a') << 4); 
      c = str.charAt(i+1); 
      bytes[i/2] += (c - 'a'); 
     } 

     return bytes; 
    } 

} 

AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.xpertwireless.newsreader"> 

    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:roundIcon="@mipmap/ic_launcher_round" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 
     <activity android:name=".MainActivity"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
     <activity android:name=".Main2Activity"></activity> 
    </application> 

</manifest> 

回答

0

你需要調用publishProgress從後臺線程,你在處理你的下載進度,您的onProgressUpdate前回調可能會被調用進度。

+0

但我甚至無法看到它一秒鐘,因爲我已經在PreExec和PostExec中包含ProgressBar。它不應該顯示至少一秒左右嗎? –