Android - after notifyDataSetChanged ListView remains blank - java

It's hours I search for something, but it doesn't seem to help.. Android Studio doesn't launch any error, but the screen remains blank. Why?
package org.newapp;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import saxrssreader.*;
public class MainActivity extends Activity {
private ArrayAdapter<RssItem> rssItemsArrayAdapter;
ListView codeLearnLessons;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RssItem[] rssItems = new RssItem[]{};
rssItemsArrayAdapter = new ArrayAdapter<RssItem>(this, android.R.layout.simple_list_item_1, rssItems);
new WebCall().execute(rssItems);
codeLearnLessons = (ListView)findViewById(R.id.listView1);
codeLearnLessons.setAdapter(rssItemsArrayAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
private class WebCall extends AsyncTask<RssItem, Void, Void> {
#Override
protected Void doInBackground(RssItem... items) {
URL url = null;
try {
url = new URL("http://www.somewpsite.com/feed");
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
ArrayList<RssItem> listItems = RssReader.read(url).getRssItems();
items = listItems.toArray(new RssItem[listItems.size()]);
final int l = items.length;
runOnUiThread(new Runnable() {
#Override
public void run() {
codeLearnLessons.invalidateViews();
rssItemsArrayAdapter.notifyDataSetChanged();
Log.i("rec", "rec" + l);
}
});
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPreExecute() {
/*ProgressDialog mDialog = new ProgressDialog(MainActivity.this);
mDialog.setMessage("Please wait...");
mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mDialog.setIndeterminate(true);
mDialog.setCancelable(false);
mDialog.show();*/
}
}
}

The issue is that your using a ArrayList which only has scope inside of the AsyncTask.doInBackground() method. Since it is not given to the adapter, the notifyDataSetChanged() does nothing. You'll need to replace the existing array like this:
rssItemsArrayAdapter.clear();
rssItemsArrayAdapter.addAll(listItems);
rssItemsArrayAdapter.notifyDataSetChanged();
Having said that, you also really need to change your use of AsyncTask. There's no need to call runOnUiThread() from within your doInBackground() as the AsyncTask will automatically run its onPostExecute() on the UI thread. Have your doInBackground() method return your new ArrayList<RssItem> and create an onPostExecute() override method which adjusts the adapter as shown above.

You are passing your items to the AsyncTask but in the AsyncTask you declare them new with the content of your result. You never pass the items to your ArrayAdapter back. Make them a property of your class instance.
Edit - Example:
rssItemsArrayAdapter.clear();
rssItemsArrayAdapter.addAll(items);
and afterwards
rssItemsArrayAdapter.notifyDataSetChanged();

Related

Issue with Http Client in android studio

I am new to android app development, and one of my clients asked me to fix this code his past dev left the job . there were a lot of errors I was able to fix it. But now I am stuck at a point in HTTP request error in java and cannot execute this code. Let me know how to fix it. Current status complied SDK 33 and cannot downgrade the same. Code below. HTTP client is deprecated.
package com.ecom.ecommerce;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.util.ArrayList;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.ProgressBar;
import android.widget.TextView;
public class ActivityCategoryList extends Activity {
GridView listCategory;
ProgressBar prgLoading;
TextView txtAlert;
// declare adapter object to create custom category list
AdapterCategoryList cla;
// create arraylist variables to store data from server
static ArrayList<Long> Category_ID = new ArrayList<Long>();
static ArrayList<String> Category_name = new ArrayList<String>();
static ArrayList<String> Category_image = new ArrayList<String>();
String CategoryAPI;
int IOConnect = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.category_list);
ActionBar bar = getActionBar();
bar.setBackgroundDrawable(new
ColorDrawable(getResources().getColor(R.color.header)));
bar.setDisplayHomeAsUpEnabled(true);
bar.setHomeButtonEnabled(true);
bar.setTitle("Category");
prgLoading = (ProgressBar) findViewById(R.id.prgLoading);
listCategory = (GridView) findViewById(R.id.listCategory);
txtAlert = (TextView) findViewById(R.id.txtAlert);
cla = new AdapterCategoryList(ActivityCategoryList.this);
// category API url
CategoryAPI = Constant.CategoryAPI+"?accesskey="+Constant.AccessKey;
// call asynctask class to request data from server
new getDataTask().execute();
// event listener to handle list when clicked
listCategory.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
// TODO Auto-generated method stub
// go to menu page
Intent iMenuList = new Intent(ActivityCategoryList.this, ActivityMenuList.class);
iMenuList.putExtra("category_id", Category_ID.get(position));
iMenuList.putExtra("category_name", Category_name.get(position));
startActivity(iMenuList);
overridePendingTransition(R.anim.open_next, R.anim.close_next);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_category, 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.
switch (item.getItemId()) {
case R.id.cart:
// refresh action
Intent iMyOrder = new Intent(ActivityCategoryList.this, ActivityCart.class);
startActivity(iMyOrder);
overridePendingTransition (R.anim.open_next, R.anim.close_next);
return true;
case R.id.refresh:
IOConnect = 0;
listCategory.invalidateViews();
clearData();
new getDataTask().execute();
return true;
case android.R.id.home:
// app icon in action bar clicked; go home
this.finish();
overridePendingTransition(R.anim.open_main, R.anim.close_next);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// clear arraylist variables before used
void clearData(){
Category_ID.clear();
Category_name.clear();
Category_image.clear();
}
// asynctask class to handle parsing json in background
public class getDataTask extends AsyncTask<Void, Void, Void>{
// show progressbar first
getDataTask(){
if(!prgLoading.isShown()){
prgLoading.setVisibility(0);
txtAlert.setVisibility(8);
}
}
#Override
protected Void doInBackground(Void... arg0) {
// TODO Auto-generated method stub
// parse json data from server in background
parseJSONData();
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
// when finish parsing, hide progressbar
prgLoading.setVisibility(8);
// if internet connection and data available show data on list
// otherwise, show alert text
if((Category_ID.size() > 0) && (IOConnect == 0)){
listCategory.setVisibility(0);
listCategory.setAdapter(cla);
}else{
txtAlert.setVisibility(0);
}
}
}
// method to parse json data from server
public void parseJSONData(){
clearData();
try {
// request data from Category API
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 15000);
HttpConnectionParams.setSoTimeout(client.getParams(), 15000);
HttpUriRequest request = new HttpGet(CategoryAPI);
HttpResponse response = client.execute(request);
InputStream atomInputStream = response.getEntity().getContent();
BufferedReader in = new BufferedReader(new InputStreamReader(atomInputStream));
String line;
String str = "";
while ((line = in.readLine()) != null){
str += line;
}
// parse json data and store into arraylist variables
JSONObject json = new JSONObject(str);
JSONArray data = json.getJSONArray("data");
for (int i = 0; i < data.length(); i++) {
JSONObject object = data.getJSONObject(i);
JSONObject category = object.getJSONObject("Category");
Category_ID.add(Long.parseLong(category.getString("Category_ID")));
Category_name.add(category.getString("Category_name"));
Category_image.add(category.getString("Category_image"));
Log.d("Category name", Category_name.get(i));
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
IOConnect = 1;
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
//cla.imageLoader.clearCache();
listCategory.setAdapter(null);
super.onDestroy();
}
#Override
public void onConfigurationChanged(final Configuration newConfig)
{
// Ignore orientation change to keep activity from restarting
super.onConfigurationChanged(newConfig);
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
finish();
overridePendingTransition(R.anim.open_main, R.anim.close_next);
}
}

How can I use a variable outside the onPostExecute method?

I have a MySQL database on a webserver and I read the data from this database in my application, but after I read the variables I can't use the "volt" variable outside the onPostExecute. I try t use adapter, but i can't use the data in the adapter like a intiger variable, just i can add to listview. So far i Don't find a solution for my problam.
I hope you can help me.
package com.example.wifis;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
public class MainActivity extends AppCompatActivity {
ListView listView;
ArrayAdapter<String> adapter;
// int tomb []={};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView=(ListView)findViewById(R.id.list_item);
adapter= new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
listView.setAdapter(adapter);
new Conection().execute();
}
class Conection extends AsyncTask<String, String, String>{
#Override
public String doInBackground(String... strings) {
String result="";
String host="http://localhost/store/cars.php";
try {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI(host));
HttpResponse response = client.execute(request);
BufferedReader reader= new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer stringBuffer= new StringBuffer("");
String line = "";
while ((line = reader.readLine()) !=null ){
stringBuffer.append(line);
break;
}
reader.close();
result = stringBuffer.toString();
}
catch (Exception e){
return new String("There exeption: "+ e.getMessage());
}
return result;
}
#Override
public void onPostExecute(String result){
// Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
JSONObject jsonResult = null;
try {
jsonResult = new JSONObject(result);
int success = jsonResult.getInt("success");
if(success==1){
JSONArray cars = jsonResult.getJSONArray("cars");
JSONObject car = cars.getJSONObject(0);
int id = car.getInt("id");
int volt = car.getInt("szam");
String line = id + "-" + volt;
adapter.add(line);
// tomb[0]=szam;
}else{
Toast.makeText(getApplicationContext(), "NOT OK ", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
As I have tried to explain in my post here
the values you're trying to access aren't synchronous, meaning that your code does not execute top down. The AsyncTask returns a value at some point. we don't know when that will be, but when it returns the value, you'll have access to it within onPostExecute. this means that you can make use of the values as they are received there and only there, as that is the only place where you'll actually receive those values.
to get this value returned to your main activity, you can do something like this :
create an interface
public interface MyCallback {
void myResult(YourResultType output); //here, i believe this will be string for your specific case
}
This interface allows us to move the value we receive to another class when it's received
Next,
Go to your AsyncTask class, and declare interface MyCallback as a variable :
public class MyAsyncTask extends AsyncTask<String, String, String> {
public MyCallback callback = null;
#Override
protected void onPostExecute(String result) {
callback.myResult(result);
}
}
#Override
protected void onPostExecute(String result) {
callback.myResult(result);
}
now for your main activity:
public class MainActivity implements MyCallback {
MyAsyncTask asyncTask = new MyAsyncTask();
#Override
public void onCreate(Bundle savedInstanceState) {
//set your listener to this class
asyncTask.callback = this;
//execute the async task
asyncTask.execute();
}
//this overrides the implemented method from asyncTask
#Override
void myResult(YourResultType output){
//Here you will receive the result returned from the async task
}
}
please also note that async tasks are deprecated
also note, my java is quite rusty, I am fortunate enough to only use kotlin these days, feel free to correct me on any mistakes :)

NullPointerExcepter Error when using List Adapter and Custom List View in Android Studio

Been trying to write an app in android studio. Part of the app has to parse a document in JSON and display two TextViews of data for each instance. One being Signal and the other being Noise. I am trying to make a custom list view in case I want to add more detail to each instance. I also would like to make it all contained in a ScrollView. I initially had no problems parsing the document but now that I am trying to implement the ListAdapter I am running into issues.
My code is giving me the error...
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.yesinc.tsi880, PID: 4919
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at com.yesinc.tsi880.TelemetryActivity$JSONTask.onPostExecute(TelemetryActivity.java:136)
at com.yesinc.tsi880.TelemetryActivity$JSONTask.onPostExecute(TelemetryActivity.java:50)
Not sure if the problem is with the document that I am trying to parse or the java code itself. Any help would be much appreciated. Code is below.
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.yesinc.tsi880.models.SondeModel;
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.URL;
import java.util.ArrayList;
import java.util.List;
import android.widget.ArrayAdapter;
public class TelemetryActivity extends AppCompatActivity {
private TextView tvData;
private ListView lvSondes;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_telemetry);
ListView lvSondes = findViewById(R.id.lvSondes);
//new JSONTask().execute("http://172.16.5.70/plots/sigstr2.txt");
}
public class JSONTask extends AsyncTask<String, String, List<SondeModel> >{
#Override
protected List<SondeModel> doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line;
while((line=reader.readLine()) != null){
buffer.append(line);
}
String finalJson = buffer.toString();
JSONObject parentObject = new JSONObject(finalJson);
JSONObject parentArray0 = parentObject.getJSONObject("0");
JSONObject parentArray1 = parentObject.getJSONObject("1");
List<SondeModel> sondeModelList = new ArrayList<>();
//StringBuffer finalBufferedData = new StringBuffer();
for(int i=0; i<8; i++){
String sonde = String.valueOf(i);
JSONObject finalObject = parentArray0.getJSONObject(sonde);
SondeModel sondeModel = new SondeModel();
sondeModel.setNoisedbm(finalObject.getString("noisedbm"));
sondeModel.setSigdbm(finalObject.getString("sigdbm"));
//String noiseDBM = finalObject.getString("noisedbm");
//String sigDBM = finalObject.getString("sigdbm");
sondeModelList.add(sondeModel);
}
for(int i=0; i<8; i++){
String sonde = String.valueOf(i);
JSONObject finalObject = parentArray1.getJSONObject(sonde);
SondeModel sondeModel = new SondeModel();
sondeModel.setNoisedbm(finalObject.getString("noisedbm"));
sondeModel.setSigdbm(finalObject.getString("sigdbm"));
//String noiseDBM = finalObject.getString("noisedbm");
//String sigDBM = finalObject.getString("sigdbm");
sondeModelList.add(sondeModel);
}
return sondeModelList;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if(connection != null) {
connection.disconnect();
}try {
if(reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(List<SondeModel> result) {
super.onPostExecute(result);
SondeAdapter adapter = new SondeAdapter(getApplicationContext(), R.layout.row, result);
lvSondes.setAdapter(adapter);
// TODO need to set a data to the List
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.navigation, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.navigation_telemetry) {
new JSONTask().execute("http://172.16.5.70/plots/sigstr2.txt");
return true;
}
return super.onOptionsItemSelected(item);
}
public class SondeAdapter extends ArrayAdapter{
public List<SondeModel> sondeModelList;
private int resource;
private LayoutInflater inflater;
public SondeAdapter(Context context, int resource, List<SondeModel> objects) {
super(context, resource, objects);
sondeModelList = objects;
this.resource = resource;
inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = inflater.inflate(resource, null);
}
TextView sig;
TextView noise;
sig = (TextView)convertView.findViewById(R.id.sig);
noise = (TextView)convertView.findViewById(R.id.noise);
sig.setText(sondeModelList.get(position).getSigdbm());
noise.setText(sondeModelList.get(position).getNoisedbm());
return convertView;
}
}
}
ListView lvSondes = findViewById(R.id.lvSondes);
You are re-declaring the lvSondes inside your onCreate method. The class member list view is never used and is never initialized. Instead a local lvSondes is initialized. This variable will not be in scope and won't be visible to the AsyncTask. The async task will use the member variable and that will be null.
Solution: remove the ListView from the stated line and just initialize the member variable

PrintWriter giving null pointer exception

I am trying to build a multiple client single java server model. I'm doing this using threads, so I have one thread per client using AsyncTask. Thus, I am creating a client socket and the PrintWriter object in the onCreate() method using the CreateClient class and then every time the button2 is pressed, I just need to pass the question/text to the server for that particular thread. The problem is, I am getting a NullPointerException in the SendMessage class.
Here's my Client Actvity:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
//import statements for client
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.speech.RecognizerIntent;
import android.speech.tts.TextToSpeech;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
//import statements for client
import android.os.AsyncTask;
public class MainActivity extends Activity implements OnClickListener {
EditText question;
//Client sockets
private Socket client;
private PrintWriter printwriter;
private String toTag;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// create client as soon as the activity starts
CreateClient clientConnection = new CreateClient();
clientConnection.execute();
question = (EditText)findViewById(R.id.editText1);
Button query = (Button)findViewById(R.id.button2);
query.setOnClickListener(this);
ImageButton listen = (ImageButton)findViewById(R.id.button1);
listen.setOnClickListener(this);
listen.performClick();
}
private class CreateClient extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
try {
client = new Socket("Server IP Address", 4444);
printwriter = new PrintWriter(client.getOutputStream(), true);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
private class CloseClient extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
if(printwriter != null) {
try {
printwriter.write("\n");
printwriter.close();
client.close(); // closing the connection
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
private class SendMessage extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
printwriter.write(toTag); // GETTING NULL POINTER EXCEPTION ON THIS LINE
printwriter.write("\n"); //delimiter
printwriter.flush();
return null;
}
}
public void onClick(View v)
{
switch(v.getId())
{
case R.id.button2:
if(validate()) //Validate is a function that validates the text
{
toTag = question.getText().toString();
//Invoke the execute method of AsynTask, which will run the doInBackground method of SendMessage Class
SendMessage sendMessageTask = new SendMessage();
sendMessageTask.execute();
}
else
{
//Toast error msg
}
break;
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
CloseClient closeConnection = new CloseClient();
closeConnection.execute();
}
}
Chances are that the line
printwriter = new PrintWriter(client.getOutputStream(), true);
isn't being executed in time. Try adding a println or initializing the printWriter somewhere else.
printWriter Object has not been initialized and it is still null which is causing Null Pointer Exception
printwriter.write(toTag);// at this line -->
So initialize printWriter=new PrintWriter(); before using it
Well, turns out my client socket wasn't getting created due to outdated DDMS in Eclipse. Something about DDMS not able to create a localhost connection on port 8600. So, as Tyler pointed, my printwriter = new PrintWriter(); statement wasn't getting executed. I updated DDMS and now it works just fine.

Receive argument Arraylist in android

I am writing a small ftp client using apache lib. I am returning list of files in ArrayList
import java.io.IOException;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import android.os.AsyncTask;
import android.util.Log;
public class myftpTask extends AsyncTask<String, Void, List<FTPFile>> {
public FTPFile[] FTPFile;
FTPClient mFtp = new FTPClient();
#Override
protected List<FTPFile> doInBackground(String... params) {
List<FTPFile> myFiles = new ArrayList<FTPFile>();
// TODO Auto-generated method stub
try {
mFtp.connect(params[0], 21);
if (FTPReply.isPositiveCompletion(mFtp.getReplyCode())) {
mFtp.login(params[1], params[2]);
mFtp.enterLocalPassiveMode();
mFtp.changeWorkingDirectory("/public_html");
FTPFile files[] = mFtp.listFiles();
for (int i = 0; i < files.length; i++) { // does not enter here
//Log.d("F-> " , ((FTPFile) files[i]).getName().toString());
//myFiles.add((FTPFile) files[i]).getName().toString());
myFiles.add(files[i]);
}
Log.v("Files", myFiles.toString());
mFtp.disconnect();
}
} catch (SocketException e) {
try {
mFtp.disconnect();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//return 1;
return myFiles;
}
}
And I am receiving it like this
import java.util.List;
import org.apache.commons.net.ftp.FTPFile;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends Activity {
#SuppressWarnings("unchecked")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv = (ListView) findViewById(R.id.listView1);
List<FTPFile> listofFiles;
listofFiles = (List<FTPFile>) new myftpTask().execute(
"*****", "*****", "******");
ArrayAdapter<FTPFile> arrayAdapter = new ArrayAdapter<FTPFile>(this,
android.R.layout.simple_list_item_1, listofFiles);
lv.setAdapter(arrayAdapter);
}
}
But it throwing an exception of cannot cast to list.
Where is the problem?
Regards
does this compile
listofFiles = (List<FTPFile>) new myftpTask().execute(
"*****", "*****", "******");
???
newmyftpTask().execute(); returns object from this type AsyncTask<String, Void, List<FTPFile>>
use this instead
listofFiles = (List<FTPFile>) new myftpTask().execute(
"*****", "*****", "******").get();
PROBLEM :
listofFiles = (List<FTPFile>) new myftpTask().execute(
"*****", "*****", "******");
you are cast wrong way
SOLUTION 1:
use get () method for getting result back from AsyncTask in main UI Thread as:
listofFiles = (List<FTPFile>) new myftpTask().execute(
"*****", "*****", "******").get();
NOTE :
this solution pause your main thread execution until response not come back from AsyncTask as doc says
SOLUTION 2:
use onPostExecute(List<FTPFile> result) for updating Ui without hanging of Ui when AsyncTask execution complete
just change your code as:
public class myftpTask extends AsyncTask<String, Void, List<FTPFile>> {
//your code here
#Override
protected void onPostExecute(List<FTPFile> result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
ArrayAdapter<FTPFile> arrayAdapter = new ArrayAdapter<FTPFile>(this,
android.R.layout.simple_list_item_1, result);
lv.setAdapter(arrayAdapter);
}
}
and start myftpTask task as from main Activity :
public class MainActivity extends Activity {
ListView lv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv = (ListView) findViewById(R.id.listView1);
new myftpTask().execute("*****", "*****", "******");
}
}
For getting return value from AsyncTask you have to use its get() method,
Replace,
listofFiles = (List<FTPFile>) new myftpTask().
execute("*****", "*****", "******");
With,
listofFiles = (List<FTPFile>) new myftpTask().
execute("*****", "*****", "******").get();
But, this will block your UI Thread. So, better would be to create an Interface or BroadCastReceiver to return the value/data from AsyncTask. Here is a demo for the same.

Categories