I get the NullPointerException and I can't figure out what's wrong. I've tried only to bring the necessary code.
I have 3 classes: MainActivity, GoogleCommunicator and CustomAdapter.
The error is caused by following in CustomAdapter:
mActivity.updateBought(position, "1");
The errors I get are line 283 and 277 which are:
283: URL listFeedUrl = mWorksheet.getListFeedUrl();
277: private class UpdateBought extends AsyncTask<Void, Void, String>
The logcat:
3011-3026/com.example.andb.apop_l6_google_communicator_app E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
Process: com.example.andb.apop_l6_google_communicator_app, PID: 3011
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.net.URL com.google.gdata.data.spreadsheet.WorksheetEntry.getListFeedUrl()' on a null object reference
at com.example.andb.apop_l6_google_communicator_app.GoogleCommunicator$UpdateBought.doInBackground(GoogleCommunicator.java:283)
at com.example.andb.apop_l6_google_communicator_app.GoogleCommunicator$UpdateBought.doInBackground(GoogleCommunicator.java:277)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
MainActivity
public class MainActivity extends ActionBarActivity implements AdapterView.OnItemClickListener{
public GoogleCommunicator mGCom = new GoogleCommunicator(this,"torprode#gmail.com");
TextView tvStatus;
EditText etAdd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvStatus = (TextView) findViewById(R.id.tvStatus);
doSomeGoogleStuff();
buttonListener();
update();
}
private void doSomeGoogleStuff(){
mGCom.setupFeed("mandatoryProject","BuyMe");
}
private void drawListview() {
ListAdapter listAdapter = new CustomAdapter(this, mGCom.listItem, mGCom.listBought);
ListView listView = (ListView) findViewById(R.id.lv_items);
listView.setAdapter(listAdapter);
}
public void updateBought(int name, String bought) {
mGCom.updateBought(name, bought);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
}
GoogleCommunicator
public class GoogleCommunicator {
//Spreadsheet communication
private static final String mScope = "oauth2:https://www.googleapis.com/auth/userinfo.profile https://spreadsheets.google.com/feeds https://docs.google.com/feeds";
private MainActivity mActivity;
private SpreadsheetService mSpreadSheetService;
private SpreadsheetFeed mFeed;
private String mSpreadsheetName;
private String mWorksheetName;
private SpreadsheetEntry mSpreadsheet;
private WorksheetEntry mWorksheet;
private String itemName;
private int itemNameIndex;
private String itemBought;
//Constructor
public GoogleCommunicator(MainActivity activity, String email) {
mEmail = email;
mActivity = activity; //possibility for callback to method in activity class
}
//Method to be called from your application.
//Creates an instance of SetupFeedTask (an AsyncTask) and executes it
public void setupFeed(String spreadsheet_name, String worksheet_name){
mSpreadsheetName = spreadsheet_name;
mWorksheetName = worksheet_name;
new SetupFeedTask().execute();
}
public void updateBought(int name, String bought) {
itemNameIndex = name;
itemBought = bought;
new UpdateBought().execute();
}
//AsyncTask that handles network comminucation e.t.c.
private class SetupFeedTask extends AsyncTask<Void, Void, String> {
//Executes in its own "worker thread" and doesnt block the main UI thread
#Override protected String doInBackground(Void... params) {
// Do work
mToken = fetchToken();
mSpreadSheetService = new SpreadsheetService("MySpreadsheetService");
mSpreadSheetService.setAuthSubToken(mToken);
URL feed_url;
try {
feed_url = new URL("https://spreadsheets.google.com/feeds/spreadsheets/private/full");
mFeed = mSpreadSheetService.getFeed(feed_url, SpreadsheetFeed.class);
}catch(MalformedURLException e){
//TODO: handle exception
Log.v(TAG, "MalformedURLException");
return null;
}catch(ServiceException e){
//TODO: handle exception
Log.v(TAG, "ServiceException");
return null;
}catch(IOException e){
//TODO: handle exception
Log.v(TAG, "IOException");
return null;
}
try{
List<SpreadsheetEntry> spreadsheets = mFeed.getEntries();
// Iterate through all of the spreadsheets returned
for (SpreadsheetEntry spreadsheet : spreadsheets) {
if (spreadsheet.getTitle().getPlainText().equals(mSpreadsheetName)) {
List<WorksheetEntry> worksheets = spreadsheet.getWorksheets();
//Iterate through worksheets
for (WorksheetEntry worksheet : worksheets) {
if (worksheet.getTitle().getPlainText().equals(mWorksheetName)) {
mSpreadsheet = spreadsheet;
mWorksheet = worksheet;
Log.v(TAG,"Spreadsheet and Worksheet is now setup.");
}
}
}
}
}catch(ServiceException e){
//TODO: handle exception
Log.v(TAG, "Service Exception");
return null;
}catch(IOException e){
//TODO: handle exception
Log.v(TAG, "IO Exception");
return null;
}
//Just for the example.. mToken not important to return
return mToken;
}
//Call back that is called when doInBackground has finished.
//Executes in main UI thread
#Override protected void onPostExecute(String result) {
//TODO: Notify rest of application, e.g.:
// * Send broadcast
// * Send message to a handler
// * Call method on Activity
}
//Helper method
private String fetchToken(){
try {
return GoogleAuthUtil.getToken(mActivity, mEmail, mScope);
} catch (UserRecoverableAuthException userRecoverableException) {
// GooglePlayServices.apk is either old, disabled, or not present, which is
// recoverable, so we need to show the user some UI through the activity.
//TODO:
if(mActivity instanceof MainActivity){
((MainActivity)mActivity).handleException(userRecoverableException);
if(D) Log.e(TAG,"UserRecoverableAuthException");
}
} catch (GoogleAuthException fatalException) {
//TODO:
//onError("Unrecoverable error " + fatalException.getMessage(), fatalException);
if(D) Log.e(TAG,"GoogleAuthException");
} catch (IOException ioException){
if(D) Log.e(TAG,"IOException");
}
return null;
}
}
private class UpdateBought extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
try {
URL listFeedUrl = mWorksheet.getListFeedUrl();
ListFeed listFeed = mSpreadSheetService.getFeed(listFeedUrl, ListFeed.class);
ListEntry row = listFeed.getEntries().get(itemNameIndex);
row.getCustomElements().setValueLocal("bought", itemBought);
row.update();
} catch (IOException e) {
e.printStackTrace();
} catch (ServiceException e) {
e.printStackTrace();
}
return null;
}
}
}
CustomAdapter
class CustomAdapter extends ArrayAdapter<String> {
ArrayList boughtList;
MainActivity mActivity = new MainActivity();
CustomAdapter(Context context, ArrayList<String> item, ArrayList<String> bought) {
super(context, R.layout.custom_listview, item);
boughtList = bought;
}
#Override
public View getView(final int position, View convertView, final ViewGroup parent) {
LayoutInflater listViewInflater = (LayoutInflater.from(getContext()));
final View customView = listViewInflater.inflate(R.layout.custom_listview, parent, false);
final String foodItem = getItem(position);
TextView foodText = (TextView) customView.findViewById(R.id.tv_Item);
final CheckBox checkBox = (CheckBox) customView.findViewById(R.id.cb_checked);
foodText.setText(foodItem);
String foodBought = String.valueOf(boughtList.get(position));
int foodBoughtInt = Integer.parseInt(foodBought);
if (foodBoughtInt == 1) {
checkBox.setChecked(true);
} else {
checkBox.setChecked(false);
}
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (checkBox.isChecked()) {
System.out.println("Jep");
mActivity.updateBought(position, "1");
} else {
System.out.println("Nope");
mActivity.updateBought(position, "0");
}
}
});
return customView;
}
}
You are encountering a race condition. You have to asynchronous tasks that execute, and the second asynchronous task depends on the first task to be done for it to work correctly. Because both tasks are done asynchronously, they are done in the background, on separate threads. Your setupFeed method is not done working, and then you start your updateBought method on a new thread. What happens is that updateBought begins while mWorksheet is still null. You will have to reorganize your code logic to avoid this race condition. What I have done in the past when I have two async tasks is to put the second asynchronous task in onPostExecute() of the first async task, because onPostExecute only occurs once doInBackground is finished.
Here is an execellent article on AsyncTasks and Threads from the developer guides.
Related
I am busy with an application where i am getting data from my azure database with sql and storing it in an array. I created a separate class where i get my data and my main activity connects to this class and then displays it.
Here is my getData class:
public class GetData {
Connection connect;
String ConnectionResult = "";
Boolean isSuccess = false;
public List<Map<String,String>> doInBackground() {
List<Map<String, String>> data = null;
data = new ArrayList<Map<String, String>>();
try {
ConnectionHelper conStr=new ConnectionHelper();
connect =conStr.connectionclass(); // Connect to database
if (connect == null) {
ConnectionResult = "Check Your Internet Access!";
} else {
// Change below query according to your own database.
String query = "select * from cc_rail";
Statement stmt = connect.createStatement();
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
Map<String,String> datanum=new HashMap<String,String>();
datanum.put("NAME",rs.getString("RAIL_NAME"));
datanum.put("PRICE",rs.getString("RAIL_UNIT_PRICE"));
datanum.put("RANGE",rs.getString("RAIL_RANGE"));
datanum.put("SUPPLIER",rs.getString("RAIL_SUPPLIER"));
datanum.put("SIZE",rs.getString("RAIL_SIZE"));
data.add(datanum);
}
ConnectionResult = " successful";
isSuccess=true;
connect.close();
}
} catch (Exception ex) {
isSuccess = false;
ConnectionResult = ex.getMessage();
}
return data;
}
}
And in my Fragmentactivity.java I simply just call the class as shown here:
List<Map<String,String>> MyData = null;
GetValence mydata =new GetValence();
MyData= mydata.doInBackground();
String[] fromwhere = { "NAME","PRICE","RANGE","SUPPLIER","SIZE" };
int[] viewswhere = {R.id.Name_txtView , R.id.price_txtView,R.id.Range_txtView,R.id.size_txtView,R.id.supplier_txtView};
ADAhere = new SimpleAdapter(getActivity(), MyData,R.layout.list_valence, fromwhere, viewswhere);
list.setAdapter(ADAhere);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
HashMap<String,Object> obj=(HashMap<String,Object>)ADAhere.getItem(position);
String ID=(String)obj.get("A");
Toast.makeText(getActivity(), ID, Toast.LENGTH_SHORT).show();
}
});
My problem comes when I want to include the onPreExecute and onPostExecute because I am relatively new to android studio and I do not know where to put the following lines of code:
#Override
protected void onPreExecute() {
ProgressDialog progress;
progress = ProgressDialog.show(MainActivity.this, "Synchronising", "Listview Loading! Please Wait...", true);
}
#Override
protected void onPostExecute(String msg) {
progress.dismiss();
}
You need to get the data from your azure database using a background service or AsyncTask. However, you are defining a class GetData which does not extend AsyncTask and hence the whole operation is not asynchronous. And I saw you have implemented doInBackground method which is not applicable here as you are not extending AsyncTask. I would suggest an implementation like the following.
You want to get some data from your azure database and want to show them in your application. In these kind of situations, you need to do this using an AsyncTask to call the server api to get the data and pass the data to the calling activity using an interface. Let us have an interface like the following.
public interface HttpResponseListener {
void httpResponseReceiver(String result);
}
Now from your Activity while you want to get the data through an web service call, i.e. AsyncTask, just the pass the interface from the activity class to the AsyncTask. Remember that your AsyncTask should have an instance variable of that listener as well. So the overall implementation should look like the following.
public abstract class HttpRequestAsyncTask extends AsyncTask<Void, Void, String> {
public HttpResponseListener mHttpResponseListener;
private final Context mContext;
HttpRequestAsyncTask(Context mContext, HttpResponseListener listener) {
this.mContext = mContext;
this.mHttpResponseListener = listener;
}
#Override
protected String doInBackground(Void... params) {
String result = null;
try {
// Your implementation of getting data from your server
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
#Override
protected void onPostExecute(final String result) {
mHttpResponseListener.httpResponseReceiver(result);
}
#Override
protected void onCancelled() {
mHttpResponseListener.httpResponseReceiver(null);
}
}
Now you need to have the httpResponseReceiver function implemented in the calling Activity. So the sample activity should look like.
public class YourActivity extends AppCompatActivity implements HttpResponseListener {
// ... Other code and overriden functions
public void callAsyncTaskForGettingData() {
// Pass the listener here
HttpRequestAsyncTask getDataTask = new HttpRequestGetAsyncTask(
YourActivity.this, this);
getDataTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
#Override
public void httpResponseReceiver(String result) {
// Get the response callback here
// Do your changes in UI elements here.
}
}
To read more about how to use AsyncTask, you might consider having a look at here.
I am trying to send an Object through Sockets using AsyncTask, but i'm getting this error (i just post the important part of it):
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #3
Process: com.mitorapps.beberconmemes, PID: 6418
java.lang.RuntimeException: An error occurred while executing doInBackground()
Caused by: java.lang.ClassCastException: java.lang.Object[] cannot be cast to com.mitorapps.beberconmemes.data.Persona[]
at com.mitorapps.beberconmemes.conexion.Enviar_Persona$MyATaskCliente.doInBackground(Enviar_Persona.java:47)
This is my Persona Class(The object that i want to send):
package com.mitorapps.beberconmemes.data;
import java.io.Serializable;
public class Persona implements Serializable{
private String Name_Persona;
String Mac_Address;
public Persona(String name_persona, String mac_address) {
this.Name_Persona = name_persona;
this.Mac_Address = mac_address;
}
public String getMac_Address() {
return this.Mac_Address;
}
public String getName_Persona() {
return this.Name_Persona;
}
public void setName_Persona(String name_Persona) {
this.Name_Persona = name_Persona;
}
}
This is my Client Class (named as Enviar_persona):
package com.mitorapps.beberconmemes.conexion;
public class Enviar_Persona extends Cliente{
private AsyncTask myATaskYW;
public Enviar_Persona(Context context){
super(context);//the client class forces to receive a context
SERVERPORT=5000;
}
#Override
public void enviar_persona(Persona p){//Method Called from view
this.myATaskYW = new MyATaskCliente();
this.myATaskYW.execute(p);
}
public void update_view(String s){//To update the State of an element on UI
TextView resp = (TextView) ((Activity)c).findViewById(R.id.resp);
resp.setText(s);
}
//AsyncTask class
class MyATaskCliente extends AsyncTask<Persona, Void, String> {
ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
System.out.println("OnPreExecute");
progressDialog = new ProgressDialog(c);
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setTitle("Connecting to server");
progressDialog.setMessage("Please wait...");
progressDialog.show();
}
#Override
protected String doInBackground(Persona... persona) {
try {
//here i'm using an static ip
Socket socket = new Socket("192.168.1.7", SERVERPORT);
//Object Send to server
ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
output.writeObject(persona[0]);
//Response recivied from server
InputStream stream = socket.getInputStream();
byte[] len=new byte[256];
stream.read(len,0,256);
String received = new String(len,"UTF-8");
socket.close();
return received;
} catch (UnknownHostException ex) {
return ex.getMessage();
} catch (IOException ex) {
return ex.getMessage();
}
}
#Override
protected void onPostExecute(String value) {
progressDialog.dismiss();
update_view(value);
}
}
}
I did it using the AsyncTask On the main activity and it works perfectly, but now that I need group my code in different classes i got the error
Instead of using
AsyncTask myATaskYW;
use
MyATaskCliente myATaskYW;
because AsyncTask is generic so the signature is replaced with Object[] array but you need to work with the specific implementation.
Note : Person[] is not a child of Object[]
I have called an async task from my button click.In the doInBackground I have called an API and It is returning me a Json object.I want to pass the Json object to another activity on the button click.How can I can get the return Json object value so that I can send it to other activity.
Thanks.
Create Interface
public interface Listener {
void success(BaseModel baseModel);
void fail(String message);
}
Create Base model class
public class BaseModel implements Serializable {
private static final long serialVersionUID = 1L;
}
Call below method inside your onClick mehtod.
protected void userLoginData(final String userName) {
// if you want to pass multiple data to server like string or json you can pass in this constructor
UserLoginLoader userLoginLoader = new UserLoginLoader(LoginActivity.this, userName, "1234567899", new Listener() {
#Override
public void success(BaseModel baseModel) {
// here you got response in object you can use in your activity
UserLoginModel userLoginModel = (UserLoginModel) baseModel;
// you can get data from user login model
}catch(Exception exception){
exception.printStackTrace();
Utils.showAlertDialog(LoginActivity.this, "Server is not responding! Try Later.");
}
}
#Override
public void fail(String message) {
}
});
userLoginLoader.execute();
}
:- User Login Loader class
public class UserLoginLoader extends AsyncTask<String, Void, Boolean> {
private Dialog dialog;
private Listener listner;
private String deviceId;
Activity activity;
String message;
String userName;
boolean checkLoginStatus;
public UserLoginLoader(Activity activity,String userName, String deviceId, Listener listener) {
this.listner = listener;
this.userName =userName;
this.activity = activity;
this.deviceId = deviceId;
}
#Override
protected Boolean doInBackground(String... arg0) {
//User login web service is only for making connection to your API return data into message string
message = new UserLoginWebService().getUserId(userName, deviceId);
if (message != "null" && !message.equals("false")) {
return true;
}
return false;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new Dialog(activity, R.style.CustomDialogTheme);
dialog.setContentView(R.layout.progress);
dialog.setCancelable(false);
dialog.show();
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
BaseModel baseModel = null;
if (!message.equals("null") && (!message.equals("false")) )
baseModel = parseData(message, result);
if (dialog.isShowing()) {
dialog.dismiss();
dialog.cancel();
dialog = null;
}
if (listner != null) {
if (result && baseModel != null)
listner.success(baseModel);
else
listner.fail("Server not responding! Try agian.");
} else
listner.fail("Server not responding! Try agian.");
}
//call parser for parsing data return data from the parser
private BaseModel parseData(String responseData, Boolean success) {
if (success == true && responseData != null
&& responseData.length() != 0) {
UserLoginParser loginParser = new UserLoginParser(responseData);
loginParser.parse();
return loginParser.getResult();
}
return null;
}
}
This is you Login parser class
public class UserLoginParser {
JSONObject jsonObject;
UserLoginModel userLoginModel;
/*stored data into json object*/
public UserLoginParser(String data) {
try {
jsonObject = new JSONObject(data);
} catch (JSONException e) {
Log.d("TAG MSG", e.getMessage());
e.printStackTrace();
}
}
public void parse() {
userLoginModel = new UserLoginModel();
try {
if (jsonObject != null) {
userLoginModel.setUser_name(jsonObject.getString("user_name")== null ? "": jsonObject.getString("user_name"));
userLoginModel.setUser_id(jsonObject.getString("user_id") == null ? "" : jsonObject.getString("user_id"));
userLoginModel.setFlag_type(jsonObject.getString("flag_type") == null ? "" : jsonObject.getString("flag_type"));
} else {
return;
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
/*return ship name list which is stored into model */
public UserLoginModel getResult() {
return userLoginModel;
}
}
Write a callback method in the Activity that takes in the argument that you wish to pass from AsyncTask to that Activity. Send reference to the Activity to AysncTask while creating it. From doInBackground() method make a call to this callback method with the data your API returns.
Code would be something like -
public class TestAsyncTask extends AsyncTask<Integer, Integer, String[]> {
Activity myActivity;
public TestAsyncTask(Activity activity) {
this.myActivity = activity;
}
#Override
protected String[] doInBackground(Integer... params) {
String data = yourApi();
myActivity.callback(data);
}
}
public class MyActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
new TestAsyncTask(this).execute(someId);
}
public void callback(String data) {
//process data
}
}
Just for the record you can directly get return value from doInBackground() method by calling get() on it.
String data = new TestAsyncTask(this).execute(someId).get();
But note this may block your UI thread as it will wait for the doInBackground() method to complete it's execution.
My program crashs after doInBackground and doesn't come to onPostExecute.
My activity code's related parts are like this:
public static class News {
private String title;
private String content;
private Bitmap image;
public News(String nTitle, String nContent, Bitmap nImage){
title = nTitle;
content = nContent;
image = nImage;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_news);
final AsyncTask task = new DatabaseConnection(this, Method.GET_ALL_NEWS).execute();
try {
task.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public final void fillListView(List<News> news){
recentNews = news;
if(recentNews != null && !recentNews.isEmpty()){
((ListView)findViewById(R.id.lvNews)).setOnItemClickListener(this);
final int size = recentNews.size();
final String newsTitles[] = new String[size];
for(int i=0; i<size; ++i)
newsTitles[i] = recentNews.get(i).title;
((ListView)findViewById(R.id.lvNews)).setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, newsTitles));
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final News selectedNews = recentNews.get(position);
startActivity(new Intent(this, ANewsActivity.class)
.putExtra("title", selectedNews.title)
.putExtra("content", selectedNews.content)
.putExtra("image", BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher)));
}
My AsyncTask code's related parts are like this:
public DatabaseConnection(Context nContext, Method nMethod){
method = nMethod;
context = nContext;
}
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(context);
progressDialog.setMessage(context.getString(R.string.database_connection_wait_message));
progressDialog.setTitle(R.string.database_connection_wait_title);
progressDialog.show();
}
#SuppressWarnings("incomplete-switch")
#Override
protected Void doInBackground(String... params) {
if(method != Method.NONE){
open();
try{
switch(method){
case GET_ALL_NEWS:
final ResultSet rs = conn.createStatement().executeQuery("select baslik, metin, resim from haberler");
news = new ArrayList<News>();
while(rs.next())
news.add(new News(rs.getString(1), rs.getString(2), BitmapFactory.decodeStream(rs.getBlob(3).getBinaryStream())));
break;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close();
}
}
return null;
}
#SuppressWarnings("incomplete-switch")
#Override
protected void onPostExecute(Void temp) {
if (progressDialog.isShowing()){
progressDialog.dismiss();
switch(method){
case GET_ALL_NEWS:
((NewsActivity)context).fillListView(news);
break;
}
method = Method.NONE;
}
}
I want UI thread waits until database operations finishes.
By the way there is no initialization problem at variables etc and database returns proper infos and my "news" variable is filled normally.
By the way again I realized it is WORKING on PHONE, STUCKS on EMULATOR interestingly (if I remove wait() method and its try-catch block on main thread code).
It's difficult to say what is crashing without the logcat output, but it would most likely be the main thread of the app because of the .wait() method you are calling in onCreate(). Your onCreate() cannot wait - it must initialize and exit, otherwise you are blocking the main thread of your app and defeating the purpose of the AsyncTask.
An Activity (SignInActivity) is calling a method in FunkcjeAPI which execute an AsyncTask.
My AsyncTask should show a ProgressDialog using an calling Activity. I don't know how to give it an correct Activity to the constructor. I tried a lot of thing, read a lot of tutorials and questions on SO, but I can't find solution. FunkcjeAPI isn't an Activity so I can't write new Logowanie(this).execute(argumenty);
AsyncTask calling code :
public class FunkcjeAPI {
static String dozwrotu = null;
public static String zalogujSie(final String nick, final String haslo)
{
String[] argumenty = {nick, haslo};
new Logowanie(/* WHAT HERE ? */).execute(argumenty); // HELP ME IN THAT LINE !!!!!!!!!!!!!
return dozwrotu;
}
My AsyncTask class code (it is in FunkcjeAPI class):
private class Logowanie extends AsyncTask<String, Void, String>
{
Activity wywolujaceActivity;
public Logowanie(Activity wywolujaceActivity) {
this.wywolujaceActivity = wywolujaceActivity;
}
#SuppressWarnings("deprecation")
#Override
protected void onPreExecute() {
wywolujaceActivity.showDialog(SignInActivit.PLEASE_WAIT_DIALOG);
}
#Override
protected String doInBackground(final String... argi) {
final JSONParser jParser = new JSONParser();
new Thread(new Runnable() {
public void run() {
final String json = jParser.getJSONFromUrl("http://tymonradzik.pl/THUNDER_HUNTER/thapi.php?q=login&username=" + argi[0] + "&password=" + argi[1] + "&imei=");
Handler mainHandler = new Handler(Looper.getMainLooper());
mainHandler.post(new Runnable() {
#Override
public void run() {
JSONObject jObject;
try {
jObject = new JSONObject(json);
Log.wtf("Link", "http://tymonradzik.pl/THUNDER_HUNTER/thapi.php?q=login&username=" + argi[0] + "&password=" + argi[1] + "&imei=");
Log.wtf("Link", json);
String error = jObject.getString("error");
if(error == "You reached daily query limit !") { nadajWartosc("You reached daily query limit !"); }
if(error == "0") {nadajWartosc(jObject.getString("token"));}
if(error == "1") {nadajWartosc("1");}
if(error == "Invalid username") {nadajWartosc("Invalid username");}
if(error == "Invalid password") {nadajWartosc("Invalid password");}
if(error == "This user is already logged in !") {nadajWartosc("This user is already logged in !");}
} catch (JSONException e1) {
e1.printStackTrace();
}
catch (NullPointerException e)
{
e.printStackTrace();
}
}
});
}}).start();
return dozwrotu;
}
#Override
protected void onPostExecute(String result) {
wywolujaceActivity.removeDialog(SignInActivit.PLEASE_WAIT_DIALOG);
}
}
Add one more parameter to zalogujSie() method that takes an Activity, and then use this parameter to start the AsyncTask:
public static String zalogujSie(Activity activity, final String nick, final String haslo)
{
// .....
new Logowanie(activity).execute(argumenty);
return dozwrotu;
}
Then you would call this method from the activity like this:
FunkcjeAPI.zalogujSie(this, "Nick", "Haslo");