如果我输入任何随机单词,它不会显示“未找到书”

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 将评估您在 MainActivityAsyncTaskonPostRequest 中编写的条件。如果空视图尚不可见,则尝试设置空视图 (Visible) 和列表视图 (Invisibe) 的可见性,反之亦然,当结果不为空时。我尝试了您在 chrome 扩展(邮递员)中使用的 api。也尝试一下以查看响应中的内容以验证代码。希望它有所帮助。如果对您有用,请接受答案。

以上是关于如果我输入任何随机单词,它不会显示“未找到书”的主要内容,如果未能解决你的问题,请参考以下文章

从 python 中的随机输入字母中查找单词。已经有啥算法可以使用/编码?

随机单词 Bash 脚本,如果提供一个数字作为第一个命令行参数,那么它将仅从具有那么多字符的单词中选择

检查 div 是不是包含这些单词中的任何一个,如果是,则显示此 div

从文本输入中突出显示 div 中的所有匹配单词

最长公共子词错误结果

循环不会迭代所有JSON数据集