如何使用“标题”更新列表视图
Posted
技术标签:
【中文标题】如何使用“标题”更新列表视图【英文标题】:How to update list view with 'titles' 【发布时间】:2019-12-07 20:40:51 【问题描述】:我正在尝试按照 Udemy“完整的 android N 开发人员课程”实施新闻阅读器应用程序。使用了列表视图。
按照我正确遵循的说明,但在执行以下主要活动时,虽然需要更新带有标题的列表项,但在列表视图中没有显示任何内容。即使在 Android 监视器中也没有错误。
请提供任何有关查找问题的建议。
谢谢!
public class MainActivity extends AppCompatActivity
ArrayList<String > titles = new ArrayList<>();
ArrayList<String> content = new ArrayList<>();
ArrayAdapter arrayAdapter;
SQLiteDatabase articleDB ;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView listView = (ListView) findViewById(R.id.listView );
arrayAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,titles);
listView.setAdapter(arrayAdapter);
articleDB = this.openOrCreateDatabase("articles",MODE_PRIVATE,null);
articleDB.execSQL("CREATE TABLE IF NOT EXISTS articles (id INTEGER PRIMARY KEY, articleID INTEGER,title VARCHAR,content VARCHAR)");
updateListView();
DownloadTask task = new DownloadTask();
try
task.execute("https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty");
catch(Exception e)
e.printStackTrace();
//update table
public void updateListView()
Cursor c = articleDB.rawQuery("SELECT * FROM articles", null);
int contentIndex = c.getColumnIndex("content");
int titleIndex = c.getColumnIndex("title");
if(c.moveToFirst())
titles.clear();
content.clear();
do
titles.add(c.getString(titleIndex));
content.add(c.getString(contentIndex));
while (c.moveToNext());
arrayAdapter.notifyDataSetChanged();
public class DownloadTask extends AsyncTask<String, Void, String>
@Override
protected String doInBackground(String... strings)
String result = "";
URL url;
HttpsURLConnection urlConnection = null;
try
url = new URL (strings[0]);
urlConnection = (HttpsURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1)
char current = (char) data;
result += current;
data = reader.read();
//Log.i("URLContent",result);
JSONArray jsonArray = new JSONArray(result);
int numberOfItems = 20;
if(jsonArray.length() <20)
numberOfItems = jsonArray.length();
//to clear the table before add data
articleDB.execSQL("DELETE FROM articles"); //will clear everything and add a new data
for (int i=0;i<numberOfItems;i++ )
//Log.i("JSONItem",jsonArray.getString(i));
String articleId = jsonArray.getString(i);
url = new URL("https://hacker-news.firebaseio.com/v0/item/"+articleId+".json?print=pretty");
urlConnection = (HttpsURLConnection) url.openConnection();
in = urlConnection.getInputStream();
reader = new InputStreamReader(in);
data = reader.read();
String articleInfo = "";
while (data!= -1)
char current = (char) data;
articleInfo += current;
data = reader.read();
//Log.i("ArticleInfo",articleInfo);
//separate title and URL
JSONObject jsonObject = new JSONObject(articleInfo);
if (!jsonObject.isNull("title") && !jsonObject.isNull("url"))
String articleTitle = jsonObject.getString("title");
String articleURL = jsonObject.getString("url");
//Log.i("info",articleTitle + articleURL);
url = new URL(articleURL);
urlConnection = (HttpsURLConnection) url.openConnection();
in = urlConnection.getInputStream();
reader = new InputStreamReader(in);
data = reader.read();
String articleContent = "";
while (data!= -1)
char current = (char) data;
articleContent += current;
data = reader.read();
//Log.i("articleContent",articleContent);
String sql = "INSERT INTO articles(articleID,title,content) VALUES(? , ? , ?)";
SQLiteStatement statement = articleDB.compileStatement(sql);
statement.bindString(1,articleId);
statement.bindString(2,articleTitle);
statement.bindString(3,articleContent);
statement.execute();
catch (MalformedURLException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
catch (JSONException e)
e.printStackTrace();
return null;
@Override
protected void onPostExecute(String s)
super.onPostExecute(s);
//run when the download task is completed
updateListView();
【问题讨论】:
尝试使用 Log 来测试连接,然后你的数据来确保它首先工作。 这里的逻辑是首先确保您收到正确的数据。第二确保数据与模型兼容并且您可以解析它。第三,它在列表中正确膨胀。所以记录所有这些步骤。但是有两个注意事项。制作两个字符串列表是不好的做法,最好制作一个对象 NEWS,例如其中包含字符串标题和字符串描述。其次是获取 JSON 的逻辑不好。改造后它可以短得多。如果您需要帮助重构,请告诉我 如果该课程学习了这种开发方式 - 将其扔进垃圾箱。尝试改造 + 回收器 + 常规型号 class= 更清洁/更快 @BorisRuzanov 感谢您的建议。我是新手,我会尝试。很抱歉我没有得到关于改造的信息:(也许我应该谷歌它。 【参考方案1】:我不认为您的问题是基于 SQLite 的,而是问题与数据的检索有关。
问题可能是:-
您没有相应的权限。因此,您需要检查您的清单是否具有权限以及您是否已请求运行时权限。见Request App Permissions
以下测试通过使用 API 24 之前的设备(模拟器)绕过运行时权限。检索时未使用适当的连接类型,即为 HTTP url 切换到 HTTP 连接。请参阅下面的代码以获取修复(可能是更好的选择)。
测试 1
例如,修改您的代码(从 中注释掉代码)以跳过数据检索并添加数据插入以进行测试显示插入的数据。
例如:-
protected String doInBackground(String... strings)
String result = "";
URL url;
HttpsURLConnection urlConnection = null;
HttpURLConnection xurlConnection = null; //ADDED for stage 2 testing
/* <<<<<<<<<<< COMMENT OUT DATA RETRIEVAL >>>>>>>>>>
try
url = new URL (strings[0]);
urlConnection = (HttpsURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1)
char current = (char) data;
result += current;
data = reader.read();
//Log.i("URLContent",result);
JSONArray jsonArray = new JSONArray(result);
int numberOfItems = 20;
if(jsonArray.length() <20)
numberOfItems = jsonArray.length();
//to clear the table before add data
articleDB.execSQL("DELETE FROM articles"); //will clear everything and add a new data
for (int i=0;i<numberOfItems;i++ )
//Log.i("JSONItem",jsonArray.getString(i));
String articleId = jsonArray.getString(i);
url = new URL("https://hacker-news.firebaseio.com/v0/item/"+articleId+".json?print=pretty");
urlConnection = (HttpsURLConnection) url.openConnection();
in = urlConnection.getInputStream();
reader = new InputStreamReader(in);
data = reader.read();
String articleInfo = "";
while (data!= -1)
char current = (char) data;
articleInfo += current;
data = reader.read();
//Log.i("ArticleInfo",articleInfo);
//separate title and URL
JSONObject jsonObject = new JSONObject(articleInfo);
if (!jsonObject.isNull("title") && !jsonObject.isNull("url"))
String articleTitle = jsonObject.getString("title");
String articleURL = jsonObject.getString("url");
//Log.i("info",articleTitle + articleURL);
url = new URL(articleURL);
xurlConnection = (HttpURLConnection) url.openConnection();
in = xurlConnection.getInputStream();
reader = new InputStreamReader(in);
data = reader.read();
String articleContent = "";
while (data!= -1)
char current = (char) data;
articleContent += current;
data = reader.read();
//Log.i("articleContent",articleContent);
String sql = "INSERT INTO articles(articleID,title,content) VALUES(? , ? , ?)";
SQLiteStatement statement = articleDB.compileStatement(sql);
statement.bindString(1,articleId);
statement.bindString(2,articleTitle);
statement.bindString(3,articleContent);
statement.execute();
catch (MalformedURLException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
catch (JSONException e)
e.printStackTrace();
<<<<<<<<<< END OF COMMENTED OUT CODE >>>>>>>>>> */
ContentValues cv = new ContentValues();
cv.put("articleID",1);
cv.put("title","Title");
cv.put("content","Some content");
articleDB.insert("articles",null,cv);
return null;
结果:-
这是预期的,即只显示标题测试 2
删除注释掉的代码,最初会产生Caused by: java.lang.SecurityException: Permission denied (missing INTERNET permission?)
测试 3
使用 API 24 之前的设备(为了方便不必请求运行时权限)并将清单更改为包含 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
结果
Caused by: java.lang.ClassCastException: com.android.okhttp.internal.huc.HttpURLConnectionImpl cannot be cast to javax.net.ssl.HttpsURLConnection
at aso.aso57271930listview.MainActivity$DownloadTask.doInBackground(MainActivity.java:117)
at aso.aso57271930listview.MainActivity$DownloadTask.doInBackground(MainActivity.java:67)
第 117 行是 urlConnection = (HttpsURLConnection) url.openConnection();
测试 4
在第 117 行添加断点并在调试模式下运行会导致:-
网址不是https而是http测试 5
按照以下方式添加行:-
protected String doInBackground(String... strings)
String result = "";
URL url;
HttpsURLConnection urlConnection = null;
HttpURLConnection xurlConnection = null; //<<<<<<<<<< ADDED for stage 2 testing
然后更改为使用:-
if (!jsonObject.isNull("title") && !jsonObject.isNull("url"))
String articleTitle = jsonObject.getString("title");
String articleURL = jsonObject.getString("url");
//Log.i("info",articleTitle + articleURL);
url = new URL(articleURL);
//urlConnection = (HttpsURLConnection) url.openConnection(); //<<<<<<<<<< commented out
xurlConnection = (HttpURLConnection) url.openConnection(); //<<<<<<<<<< added to replace commented out line.
in = urlConnection.getInputStream();
reader = new InputStreamReader(in);
data = reader.read();
String articleContent = "";
while (data!= -1)
char current = (char) data;
articleContent += current;
data = reader.read();
//Log.i("articleContent",articleContent);
String sql = "INSERT INTO articles(articleID,title,content) VALUES(? , ? , ?)";
SQLiteStatement statement = articleDB.compileStatement(sql);
statement.bindString(1,articleId);
statement.bindString(2,articleTitle);
statement.bindString(3,articleContent);
statement.execute();
结果:-
【讨论】:
感谢您为提供详细答案所做的努力! 感谢您的解释。【参考方案2】:您的表没有在数据库中创建,请更改
articleDB.execSQL("CREATE TABLE IF NOT EXISTS articles (id INTEGER PRIMARY KEY, articleID INTEGER,title VARCHAR,content VARCHAR)");
到
articleDB.execSQL("CREATE TABLE IF NOT EXISTS articles (id INTEGER PRIMARY KEY, articleID INTEGER,title TEXT,content TEXT)");
【讨论】:
谢谢,我按照建议进行了尝试,但输出相同,列表视图中没有标题。在运行控制台中,长时间显示为“正在启动应用程序”,没有任何其他输出,甚至没有错误。以上是关于如何使用“标题”更新列表视图的主要内容,如果未能解决你的问题,请参考以下文章