【问题标题】:Why is this array not populated?为什么这个数组没有填充?
【发布时间】:2014-10-03 02:27:03
【问题描述】:

我有一个函数 prettyPrint(),它应该在执行 Youtube 搜索后用字符串填充数组。当我尝试使用 ArrayAdapter 从另一个活动访问它时,应用程序崩溃并且 logcat 告诉我该数组为空。

这是我定义方法 prettyPrint()、SearchYoutube.java 的类(这是最后一个方法):

package com.example.activity2;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.ResourceId;
import com.google.api.services.youtube.model.SearchListResponse;
import com.google.api.services.youtube.model.SearchResult;
import com.google.api.services.youtube.model.Thumbnail;

/**
 * Print a list of videos matching a search term.
 *
 * @author Jeremy Walker
 */
public class SearchYoutube {


       public static List<SearchResult> searchListResults = new ArrayList();

    /**
     * Define a global variable that identifies the name of a file that
     * contains the developer's API key.
     */
    private static final String PROPERTIES_FILENAME = "youtube.properties";

    private static final long NUMBER_OF_VIDEOS_RETURNED = 25;
    public static String [] ytstuff = new String[(int) NUMBER_OF_VIDEOS_RETURNED];

    /**
     * Define a global instance of a Youtube object, which will be used
     * to make YouTube Data API requests.
     */
    private static YouTube youtube;

    /**
     * Initialize a YouTube object to search for videos on YouTube. Then
     * display the name and thumbnail image of each video in the result set.
     *
     * @param args command line args.
     */
    public static void main(String[] args) {
        // Read the developer key from the properties file.
        Properties properties = new Properties();
        try {
            InputStream in = SearchActivity.class.getResourceAsStream("/" + PROPERTIES_FILENAME);
            properties.load(in);

        } catch (IOException e) {
            System.err.println("There was an error reading " + PROPERTIES_FILENAME + ": " + e.getCause()
                    + " : " + e.getMessage());
            System.exit(1);
        }

        try {
            // This object is used to make YouTube Data API requests. The last
            // argument is required, but since we don't need anything
            // initialized when the HttpRequest is initialized, we override
            // the interface and provide a no-op function.
            youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, new HttpRequestInitializer() {
                public void initialize(HttpRequest request) throws IOException {
                }
            }).setApplicationName("youtube-cmdline-search-sample").build();

            // Prompt the user to enter a query term.
            String queryTerm = getInputQuery();

            // Define the API request for retrieving search results.
            YouTube.Search.List search = youtube.search().list("id,snippet");

            // Set your developer key from the Google Developers Console for
            // non-authenticated requests. See:
            // https://console.developers.google.com/
            String apiKey = properties.getProperty("youtube.apikey");
            search.setKey(apiKey);
            search.setQ(queryTerm);

            // Restrict the search results to only include videos. See:
            // https://developers.google.com/youtube/v3/docs/search/list#type
            search.setType("video");

            // To increase efficiency, only retrieve the fields that the
            // application uses.
            search.setFields("items(id/kind,id/videoId,snippet/title,snippet/thumbnails/default/url)");
            search.setMaxResults(NUMBER_OF_VIDEOS_RETURNED);

            // Call the API and print results.
            SearchListResponse searchResponse = search.execute();
            List<SearchResult> searchResultList = searchResponse.getItems();
            searchListResults = searchResultList;
            if (searchResultList != null) {
                prettyPrint(searchResultList.iterator(), queryTerm);
            }
        } catch (GoogleJsonResponseException e) {
            System.err.println("There was a service error: " + e.getDetails().getCode() + " : "
                    + e.getDetails().getMessage());
        } catch (IOException e) {
            System.err.println("There was an IO error: " + e.getCause() + " : " + e.getMessage());
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    /*
     * Prompt the user to enter a query term and return the user-specified term.
     */
    private static String getInputQuery() throws IOException {

        String inputQuery = "";

        System.out.print("Please enter a search term: ");
        BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
        inputQuery = bReader.readLine();

        if (inputQuery.length() < 1) {
            // Use the string "YouTube Developers Live" as a default.
            inputQuery = "YouTube Developers Live";
        }
        return inputQuery;
    }

    /*
     * Prints out all results in the Iterator. For each result, print the
     * title, video ID, and thumbnail.
     *
     * @param iteratorSearchResults Iterator of SearchResults to print
     *
     * @param query Search query (String)
     */
    public static void prettyPrint(Iterator<SearchResult> iteratorSearchResults, String query) {

        if (!iteratorSearchResults.hasNext()) {        }

        while (iteratorSearchResults.hasNext()) {

            SearchResult singleVideo = iteratorSearchResults.next();
            ResourceId rId = singleVideo.getId();

            // Confirm that the result represents a video. Otherwise, the
            // item will not contain a video ID.
            if (rId.getKind().equals("youtube#video")) {
                Thumbnail thumbnail = singleVideo.getSnippet().getThumbnails().getDefault();
                for (int i=0;i<25;i=i+2)
                {
                    for (int j= 1;j <26;i=i+2)
                    {
                        if (j-i == 1)
                        {
                ytstuff[i] = rId.getVideoId(); //first thing is video id
                ytstuff[j] = singleVideo.getSnippet().getTitle(); //second thing is title
                        }
            }
        }
    } 


}
    }
}

这是我调用 prettyPrint() 的活动,SearchActivity.java

package com.example.activity2;


import java.util.ArrayList;
import java.util.Iterator;

import android.app.Activity;
import android.app.SearchManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.api.services.youtube.model.SearchResult;



public class SearchActivity extends Activity implements AdapterView.OnItemClickListener {
    ListView lst;





@Override
protected void onCreate(Bundle savedInstanceState) 
{

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_search_activity);
    Intent intent = getIntent();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
      String query = intent.getStringExtra(SearchManager.QUERY);
      Iterator<SearchResult> it = SearchYoutube.searchListResults.iterator();
      SearchYoutube.prettyPrint(it, query);
      lst = (ListView) findViewById(R.id.list);
      ArrayAdapter<String> adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1,SearchYoutube.ytstuff);
      lst.setAdapter(adapter);
      lst.setOnItemClickListener(this);
}
}
@Override 
public void onItemClick(AdapterView<?> adapterView, View view,int i, long l)
{
    TextView temp= (TextView) view;
    Toast.makeText(this,temp.getText()+""+i,Toast.LENGTH_SHORT).show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.search, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

}

我有一种预感,我可能误解了 Youtube API 方法的确切作用。如果我只是创建一个字符串数组并将其传递给适配器,SearchActivity 中的代码就可以完美运行,所以我认为 SearchYoutube 类有问题。

【问题讨论】:

  • 可能与您的问题无关,但 if (!iteratorSearchResults.hasNext()) { } 行到底在做什么?此外,您应该真正考虑使用具有 系统的 HashMap——这似乎是您试图用那个古怪的双 for 循环创建的东西。这是一个懒惰的诊断,但它会让您的代码更具可读性并可能解决您的问题。
  • 该方法最初是为了打印结果,并且会打印“无结果”或类似的内容。不,我没有堆栈跟踪。不完全确定那是什么。我对编程比较陌生。
  • 是的,使用映射结构很有意义,但现在我只是想从 Youtube 获取一些虚拟数据到列表中并在屏幕上查看。此时真的只是感觉一下 Youtube API。
  • 嗯,我觉得我做的很简单。只需遍历偶数位置,将 ID 放入其中,然后遍历奇数位置并将标题放入其中。
  • “我认为我所做的很简单”不。这很简单:一个名为 VideoMetaData 的类,其中包含您想要的任何内容,例如 ID 和 Title ` while(iteraterThing.hasNext()){ if(some condition){ VideoMetaData videoData = New VideoMetaData();视频数据.setID(...); videoData.setTitle(....); listOfVideoData.add(videoData); } }` 你所做的本质上是创建自己的非常粗糙的数据对象,该对象极难更改,依赖于不寻常的参数(i 和 j),并且运行非常糟糕(O(n ^ 2))。为了你的未来,改变它。

标签: java android arrays youtube youtube-api


【解决方案1】:

第二个 for 循环从不将 j 递增,而是将 i 递增 2。

【讨论】:

  • 好收获。没有解决我的问题,但仍然很好。我的 ArrayAdapter 仍然导致程序崩溃,表现得好像字符串数组为空。
猜你喜欢
  • 1970-01-01
  • 2014-09-07
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
  • 2020-04-28
  • 2016-12-27
  • 2016-10-30
  • 2016-06-11
相关资源
最近更新 更多