Android如何从HTTP服务器文本文件读取内容设置到TextView
Hey there! Let's walk through fixing your code so it can properly fetch the text file from the server and display it in your TextView. I notice a couple of key issues in your current implementation that we'll address step by step:
Key Issues in Your Current Code
- Network Operations on Main Thread: Android blocks network calls on the main thread (to keep the app responsive), so your
getCurrentSong()call inonCreate()will throw aNetworkOnMainThreadException. - Variable Scope Problem: The
strvariable insidegetCurrentSong()is a local variable — it doesn't update the class-levelstryou're trying to use insetText(). That's why your TextView will show "Now Playing: null". - UI Update Timing: Even if the network call worked, you're trying to set the TextView immediately after calling
getCurrentSong(), which won't wait for the network request to finish.
Fixed Implementation
First, make sure you add the INTERNET permission to your AndroidManifest.xml (this is mandatory for network access):
<uses-permission android:name="android.permission.INTERNET" />
Here's the corrected MainActivity code, using AsyncTask to handle the network request in a background thread and update the UI safely:
package com.mycompany.myapp3; import android.app.Activity; import android.os.AsyncTask; import android.os.Bundle; import android.widget.TextView; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; public class MainActivity extends Activity { private TextView songTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Initialize the TextView once for efficiency songTextView = findViewById(R.id.songtextview); // Start the background task to fetch the remote text file new FetchTextTask().execute(); } // AsyncTask handles background network work and safe UI updates private class FetchTextTask extends AsyncTask<Void, Void, String> { @Override protected String doInBackground(Void... voids) { String fetchedText = null; try { URL url = new URL("http://adovex.com/test.txt"); BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); fetchedText = in.readLine(); in.close(); } catch (Exception e) { e.printStackTrace(); fetchedText = "Error loading content"; // Fallback for failed requests } return fetchedText; } @Override protected void onPostExecute(String result) { // This method runs on the main thread, so it's safe to update UI here if (result != null) { songTextView.setText("Now Playing: " + result); } else { songTextView.setText("Failed to load song info"); } } } }
What Changed & Why
AsyncTask Usage:
doInBackground()runs the network request on a background thread, avoiding the main thread network exception.onPostExecute()triggers automatically when the background task finishes, and it runs on the main thread — so we can safely update the TextView here.
Variable & View Optimization:
- We initialize
songTextViewonce inonCreate()instead of fetching it multiple times, which is more efficient. - The fetched text is passed directly from the background thread to the UI thread, eliminating the scope issue with your original
strvariable.
- We initialize
Error Handling:
- Added fallback messages for failed network requests, so your app doesn't just show empty content if something goes wrong.
For Future Auto-Refresh (Every Few Minutes)
If you want to refresh the content periodically later, you can use a Handler to trigger the task on a schedule. Add this to onCreate() to refresh every 5 minutes:
new android.os.Handler().postDelayed(new Runnable() { @Override public void run() { new FetchTextTask().execute(); // Repeat every 5 minutes (300000 milliseconds) new android.os.Handler().postDelayed(this, 300000); } }, 300000);
内容的提问来源于stack exchange,提问作者William W Valentine

