如果我输入任何随机单词,它不会显示“未找到书”
Posted
技术标签:
【中文标题】如果我输入任何随机单词,它不会显示“未找到书”【英文标题】:if i enter any random words it is not displaying "NO book found" 【发布时间】:2017-02-24 21:59:20 【问题描述】:我在我的 android book 列表应用程序中使用 google books api 一切正常,但是当他们没有找到书时,我无法将 setEmptyView() 用于 listView,它说的是 AsyncTask doInBackground 中存在一些错误 下面是我的代码和 logcat
Books.java //书籍详情
package com.example.ashis.booklisting;
/**
* Created by ashis on 10/14/2016.
*/
public class Books
private String bookTitle;
private String bookAuthor;
private String bookPublisher;
private String mUrl;
public Books(String bookTitle, String bookAuthor, String bookPublisher, String Url)
this.bookTitle = bookTitle;
this.bookAuthor = bookAuthor;
this.bookPublisher = bookPublisher;
mUrl=Url;
public String getmUrl()
return mUrl;
public String getBookTitle()
return bookTitle;
public String getBookAuthor()
return bookAuthor;
public String getBookPublisher()
return bookPublisher;
activity_main.xml // 声明 listView 的地方
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
tools:context="com.example.ashis.booklisting.MainActivity">
<ListView
android:layout_
android:layout_
android:id="@+id/list"
/>
<TextView
android:layout_
android:layout_
android:id="@+id/emptyView"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
activity_search // 标题/发布者/作者搜索的按钮和编辑文本
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.ashis.booklisting.Search_Activity">
<EditText
android:layout_
android:layout_
android:id="@+id/editText_search"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="159dp"
android:minWidth="300dp"
android:hint="title/author/publisher"
android:minLines="1" />
<Button
android:layout_
android:layout_
android:text="search"
android:id="@+id/button_search"
android:layout_below="@+id/editText_search"
android:layout_centerHorizontal="true"
android:layout_marginTop="93dp" />
</RelativeLayout>
自定义布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_
android:layout_>
<TextView
android:layout_
android:layout_
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="@+id/textView_title"
android:layout_gravity="center_horizontal" />
<TextView
android:layout_
android:layout_
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="@+id/textView_author" />
<TextView
android:layout_
android:layout_
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="@+id/textView_publisher" />
</LinearLayout>
customAdapter.java
package com.example.ashis.booklisting;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import java.util.ArrayList;
/**
* Created by ashis on 10/14/2016.
*/
public class CustomAdapter extends ArrayAdapter<Books>
public CustomAdapter(Activity context, ArrayList<Books> booksArrayList)
super(context,0,booksArrayList);
@Override
public View getView(int position, View convertView, ViewGroup parent)
View rootView = convertView;
if (rootView== null)
rootView= LayoutInflater.from(getContext()).inflate(R.layout.custom_layout,parent,false);
final Books currentBook = getItem(position);
String title = currentBook.getBookTitle();
TextView titleText = (TextView) rootView.findViewById(R.id.textView_title);
titleText.setText(title);
String author = currentBook.getBookAuthor();
TextView authorText = (TextView) rootView.findViewById(R.id.textView_author);
authorText.setText(author);
String publisher = currentBook.getBookPublisher();
TextView publisherText = (TextView)rootView.findViewById(R.id.textView_publisher);
publisherText.setText(publisher);
return rootView;
MainActivity.java
package com.example.ashis.booklisting;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity
private TextView emptyText;
private CustomAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
emptyText=(TextView) findViewById(R.id.emptyView);
Intent intent = getIntent();
String qry = intent.getStringExtra("searchQuery");
Log.i("qry",qry);
if (qry.contains(" "))
qry.replace(" ","+");
String JSON_RESPONSE = "https://www.googleapis.com/books/v1/volumes?q="+qry;
Log.i("JSON",JSON_RESPONSE);
ListView listView = (ListView) findViewById(R.id.list);
adapter=new CustomAdapter(this,new ArrayList<Books>());
listView.setAdapter(adapter);
BookAsyncTask task = new BookAsyncTask();
task.execute(JSON_RESPONSE);
listView.setEmptyView(emptyText);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
Books books = adapter.getItem(position);
Uri booksUri = Uri.parse(books.getmUrl());
Intent webIntent = new Intent(Intent.ACTION_VIEW,booksUri);
startActivity(webIntent);
);
private class BookAsyncTask extends AsyncTask<String,Void,List<Books>>
@Override
protected List<Books> doInBackground(String... urls)
if (urls.length<1 || urls[0]==null)
return null;
List<Books> result = QueryUtils.fetchBookData(urls[0]);
return result;
@Override
protected void onPostExecute(List<Books> books)
adapter.clear();
if (books!=null && !books.isEmpty())
adapter.addAll(books);
emptyText.setText("No books Found");
QueryUtils.java
package com.example.ashis.booklisting;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
/**
* Created by ashis on 10/14/2016.
*/
public class QueryUtils
public QueryUtils()
public static List<Books> fetchBookData(String requestUrl)
URL url = createUrl(requestUrl);
String jsonResponse = makeHTTP(url);
List<Books> books = extractFromJson(jsonResponse);
return books;
private static URL createUrl(String requestUrl)
URL url = null;
try
url=new URL(requestUrl);
try
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();
catch (URISyntaxException e)
e.printStackTrace();
catch (MalformedURLException e)
e.printStackTrace();
return url;
public static List<Books> extractFromJson(String jsonResponse)
if (TextUtils.isEmpty(jsonResponse))
return null;
final List<Books> booksArray = new ArrayList<>();
try
JSONObject root = new JSONObject(jsonResponse);
JSONArray itemsArray = root.optJSONArray("items");
Log.i("length",String.valueOf(itemsArray.length()));
for (int i=0;i<itemsArray.length();i++)
JSONObject singleItem = itemsArray.getJSONObject(i);
JSONObject volumeInfo = singleItem.getJSONObject("volumeInfo");
String title = volumeInfo.getString("title");
Log.i("title_book",title);
String author = volumeInfo.getString("authors");
Log.i("author_book",author);
String publisher = volumeInfo.getString("publisher");
Log.i("publisher_book",publisher);
String website = volumeInfo.getString("previewLink");
Log.i("url",website);
booksArray.add(new Books(title,author,publisher,website));
catch (JSONException e)
e.printStackTrace();
return booksArray;
public static String makeHTTP(URL url)
String jsonResponse = "";
if (url == null)
return jsonResponse;
HttpURLConnection connection = null;
InputStream inputStream = null;
try
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setReadTimeout(10000);
connection.setConnectTimeout(15000);
connection.connect();
int serverCode = connection.getResponseCode();
Log.i("server_Code",String.valueOf(serverCode));
if (serverCode == 200)
inputStream = connection.getInputStream();
jsonResponse = readFromInputStream(inputStream);
catch (IOException e)
e.printStackTrace();
finally
if (connection!=null)
connection.disconnect();
if (inputStream!=null)
try
inputStream.close();
catch (IOException e)
e.printStackTrace();
return jsonResponse;
private static String readFromInputStream(InputStream inputStream) throws IOException
StringBuilder output = new StringBuilder();
if (inputStream!= null)
InputStreamReader inputReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader bufferReader = new BufferedReader(inputReader);
String line = bufferReader.readLine();
while (line != null)
output.append(line);
line = bufferReader.readLine();
return output.toString() ;
SearchActivity.java
package com.example.ashis.booklisting;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class Search_Activity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_);
final EditText editText_search = (EditText) findViewById(R.id.editText_search);
Button buttonSearch = (Button) findViewById(R.id.button_search);
buttonSearch.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
String searchText = editText_search.getText().toString();
Intent intent = new Intent(getApplicationContext(),MainActivity.class);
intent.putExtra("searchQuery",searchText);
startActivity(intent);
);
manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.ashis.booklisting">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
</activity>
<activity android:name=".Search_Activity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
日志猫
FATAL EXCEPTION: AsyncTask #9
Process: com.example.ashis.booklisting, PID: 5084
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:309)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int org.json.JSONArray.length()' on a null object reference
at com.example.ashis.booklisting.QueryUtils.extractFromJson(QueryUtils.java:69)
at com.example.ashis.booklisting.QueryUtils.fetchBookData(QueryUtils.java:38)
at com.example.ashis.booklisting.MainActivity$BookAsyncTask.doInBackground(MainActivity.java:58)
at com.example.ashis.booklisting.MainActivity$BookAsyncTask.doInBackground(MainActivity.java:51)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
【问题讨论】:
根据错误,空视图不是问题...无论如何,我会考虑使用 SearchView 类。没有太多理由让 Activity 仅用于搜索 【参考方案1】:QueryUtils 中的以下行导致崩溃:
Log.i("length",String.valueOf(itemsArray.length()));
这也表明 root 对象可能不包含 items 数组。 调试您的应用程序并在以下行检查结果:
JSONArray itemsArray = root.optJSONArray("items");
若要移除异常,请添加检查 itemsArray 是否为空,并相应地为函数返回值。
【讨论】:
如果 itemsArray 为 null 我应该返回 null 吗? 是,您应该返回 null。因为返回 null 将评估您在 MainActivity 内 AsyncTask 的 onPostRequest 中编写的条件。如果空视图尚不可见,则尝试设置空视图 (Visible) 和列表视图 (Invisibe) 的可见性,反之亦然,当结果不为空时。我尝试了您在 chrome 扩展(邮递员)中使用的 api。也尝试一下以查看响应中的内容以验证代码。希望它有所帮助。如果对您有用,请接受答案。以上是关于如果我输入任何随机单词,它不会显示“未找到书”的主要内容,如果未能解决你的问题,请参考以下文章
从 python 中的随机输入字母中查找单词。已经有啥算法可以使用/编码?
随机单词 Bash 脚本,如果提供一个数字作为第一个命令行参数,那么它将仅从具有那么多字符的单词中选择