所以我得到了这个类,假设要获取一个json文件,然后将其解析成一个jsonObject,稍后将变成我将在我的片段中处理的Calendar实例列表。
目前,我正在doInBackground函数中执行请求和解析json对象,并返回Calendar实例列表。我几乎没有使用线程,也没有Android工作室的AsyncTask。
但是我收到以下错误(请参阅logcat)
09-19 20:08:46.614 13504-13504/com.abc.socke.abcE/AndroidRuntime: FATAL EXCEPTION: main
Process: com.abc.socke.abc, PID: 13504
java.lang.ClassCastException: com.abc.socke.abc.Calendar cannot be cast to java.util.List
at com.abc.socke.abc.CalendarFragment.onCreateView(CalendarFragment.java:46)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2354)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1419)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1740)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1809)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:799)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2580)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2367)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2199)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:651)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:145)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1236)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:662)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:624)
at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:605)
at android.support.design.widget.TabLayout$ViewPagerOnTabSelectedListener.onTabSelected(TabLayout.java:2170)
at android.support.design.widget.TabLayout.dispatchTabSelected(TabLayout.java:1165)
at android.support.design.widget.TabLayout.selectTab(TabLayout.java:1158)
at android.support.design.widget.TabLayout.selectTab(TabLayout.java:1128)
at android.support.design.widget.TabLayout$Tab.select(TabLayout.java:1427)
at android.support.design.widget.TabLayout$TabView.performClick(TabLayout.java:1537)
at android.view.View$PerformClick.run(View.java:24697)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
在我试图打电话的片段中,我指引我到这一行。
calendarEvents = (List<Calendar>) new Calendar().execute("https://api.myjson.com/bins/7cp25");
问题: 我究竟做错了什么?
我应该将我的http请求解析为JsonObject,然后在onPostExecute而不是doInBackground中创建我的Calendar实例吗?
尝试任何帮助人!
package com.MyAppName.Myname.MyAppName;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.util.Log;
import com.facebook.GraphResponse;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.simple.parser.JSONParser;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
public class Calendar extends AsyncTask<String, Void, List<Calendar>> {
private String SUMMARY;
private String DTSTART;
private String data;
public static final String REQUEST_METHOD = "GET";
public static final int READ_TIMEOUT = 15000;
public static final int CONNECTION_TIMEOUT = 15000;
public String getEventSummary() {
return SUMMARY;
}
public String getEventTime() {
return DTSTART;
}
public Calendar(String eventName, String etimeStamp) {
SUMMARY = eventName;
DTSTART = etimeStamp;
}
public Calendar() {
}
@Override
protected List<Calendar> doInBackground(String... params) {
String inputUrl = params[0];
Log.v("PARAMS[0] URL: ", inputUrl);
try {
URL url = new URL(inputUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//Set methods and timeouts
connection.setRequestMethod(REQUEST_METHOD);
connection.setReadTimeout(READ_TIMEOUT);
connection.setConnectTimeout(CONNECTION_TIMEOUT);
//Connect to our url
connection.connect();
InputStream inputStream = connection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = "";
while (line != null) {
line = bufferedReader.readLine();
data = data + line;
}
} catch (MalformedURLException e) {
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("FETCHCALENDAREVENT");
List<Calendar> allCalendarEvents = new ArrayList<Calendar>();
try {
JSONObject JsonData = new JSONObject(data);
JSONArray data = JsonData.getJSONArray("VEVENT");
for (int i = 0; i < data.length(); i++) {
JSONObject jsonData = data.getJSONObject(i);
String event_name = jsonData.getString("SUMMARY");
String timeStamp = jsonData.getString("DTSTART;VALUE=DATE");
Calendar calendarEvent = new Calendar(event_name, timeStamp);
allCalendarEvents.add(calendarEvent);
}
} catch (JSONException e) {
e.printStackTrace();
}
Log.v("KOM HIT", "SKODKSODSODKOS");
Log.v("all allCalendarEvents!", allCalendarEvents.get(2).getEventSummary());
return allCalendarEvents;
}
protected void onPostExecute(List<Calendar> allCalendarEvents) {
super.onPostExecute(allCalendarEvents);
}
}
更新:我尝试在onPostExecute中执行我的操作。不过这里有什么问题?:
ArrayList<String> calendarItems = new ArrayList<String>();
CalendarFragment.listView = CalendarFragment.view.findViewById(R.id.calendar_list_view);
for(int i = 0; i < allCalendarEvents.size(); i++){
calendarItems.add(i, allCalendarEvents.get(i).getEventSummary().toString() + "\n" + allCalendarEvents.get(i).getEventTime().toString());
}
if(CalendarFragment.listView != null){
ArrayAdapter<String> listViewAdapter = new ArrayAdapter<String>(
CalendarFragment.context,
android.R.layout.simple_list_item_2,
calendarItems);
CalendarFragment.listView.setAdapter(listViewAdapter);
我用CalendarFragment.context替换了getActivity(),以便更新正确的,我也调用了CalendarFragment.listview。我应该以另一种方式做到这一点吗?
答案 0 :(得分:0)
在这一行
calendarEvents = (List<Calendar>) new Calendar().execute("https://api.myjson.com/bins/7cp25");
您正在尝试将Calendar
instace(它是您执行()方法返回的AsyncTask
实例)转换为List
。这是完全不同的类型 - 这就是你得到ClassCastException
的原因。
除此之外,您在代码中做了很奇怪的事情:您使用与结果类型相同的AsyncTasks列表来参数化AsyncTask
任务。我非常怀疑这是你的意图。
答案 1 :(得分:0)
我认为你对AsyncTask有一点误解。
问题是您正在创建AsyncTask对象并尝试将其分配给List类型的对象。因此,抛出异常。
在AsyncTask doInBackground
中,执行您的工作。工作完成后会返回return语句:
return allCalendarEvents;
该对象(在本例中为Calender对象列表)将返回到AsyncTask onPostExecute
方法。
您希望对doInBackground
中的列表执行有用的操作。您可以将其交还给调用.execute
的班级,或者您可以执行其他操作,这取决于您。
答案 2 :(得分:0)
您想要的是将数据从AsyncTask类传递回调用者类。使用execute语句,您希望返回List。我假设你认为doInBackground()(在你的情况下是List)的返回值将由execute()调用返回。那是错的。这不是AsyncTask的工作原理。 doInBackground()的返回值作为结果赋予onPostExecute()。
你想要的是一个接口实现。 在您的日历类中
public interface IfaceCalendar {
void onCalendaruResult(List<Calendar> list);
}
public IfaceCalendar listener;
public void SetListener(IfaceCalendar listener) {
this.listener = listener;
}
因此,上面的代码设置了一个接口,可以异步地将结果返回给调用者片段。
您应该使用listener.onCalendarResult(list)
来呼叫监听器。但是这个语句不应该在你的doInBackground()中。 doInBackground在后台线程上运行。您希望在UI线程中返回这些结果。因此,重写AsyncTask的onPostExecute()函数并通过那里返回结果。
@Override
public void onPostExecute(List<Calendar> list)
{
if (listener != null) {
listener.onCalendarResult(list);
}
}
最后,您需要在执行任务
之前在片段中设置侦听器Calendar c = new Calendar();
c.SetListener(this);
c.execute("https://api.myjson.com/bins/7cp25");
您可以覆盖片段中的onCalendarResult()函数,接收结果并执行您想要的任何操作。以下是它的实现方式:
@Override
public void onCalendarResult(List<Calendar> list) {
// You have your list here. Do what you want with it
}