0

I have an application in android in which I'm accessing data from server which is accessed using a separate class LongOperation which extends AsyncTask. Now I get the data in the LongOperation Class, but I'm not able to copy this data in another classes object where I need to use it to store in a sqlitedb. I have tried directly writing the data to sqlitedb, but given that the class LongOperation is not an activity, I cannot pass context in super(new MainActivity(), DATABASE_NAME, null, DATABASE_VERSION); as required by sqlitedb. The object in which data is fetched is accessed using a class library. I call the LongOperation class from button click in my MainActivity class which is also an activity, but the context from here doesn't work. Following are the related excerpts which depict the calling and data fetch procedure.

MainActivity button Press code(in separate file)

import LibPack.UpdateData;
public static UpdateData upd;

public void onClick(View arg0) {
            upd = new UpdateData();
            LongOperation.getUserData = true;
            lo = new LongOperation();
            lo.execute("");
        }

LongOperation class code(in separate file)

import LibPack.UpdateData;

public static class LongOperation extends AsyncTask<String, Void, String> {
    public static UpdateData upd;
    @Override
    protected String doInBackground(String... params) {
        if (getUserData) {
            upd  = *data fetched from server*
        }
}

So how do I return data from this class back to the MainActivity? Or if there is some other way to store the data in a file so that I can access it via other class? The data in object is of string[] format and key value pair. The problem here is caused due to the class LongOperation being a non-activity class, hence there is no way to pass context while using file writer or sharedpreferences.

Edit 1:

MainActivity

package com.sam.vehicle;


import com.example.vehicle.R;
import com.sam.vehicle.CommonData.LongOperation;

import LibPack.UpdateData;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;


public class MainActivity extends Activity implements AsyncResponse{
    Button b;
    public static LongOperation lo = new LongOperation();
    public static String resp;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lo.delegate = this;
        b = (Button) findViewById(R.id.btnProceed);
        b.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                upd = new UpdateData();
                CommonData.getUserData = true;
                System.out.println("Before execute");**//prints fine**
                lo.execute("");
                System.out.println("At main extract");**//prints with previous sysout**
                System.out.println("At main extract resp = "+resp);**//prints = null**
                Intent ii = new Intent(arg0.getContext(), LoginActivity.class);
                ii.putExtra("number", phoneNumber.getText().toString());        
                startActivity(ii);
            }
        });
}
    @Override
    public void processFinish(String output) {
        // TODO Auto-generated method stub
        System.out.println("Executed processFinish in main. output = "+output);**//doesn't print
        resp = output;
    }
}

AsyncTask Class:

package com.sam.vehicle;

import com.example.vehicle.R;


public class CommonData {

    public static boolean getUserData = false;
    public static String resp;
        public static class LongOperation extends AsyncTask<String, Void, String> {
            public AsyncResponse delegate = null;

            @Override
            protected void onPostExecute(String result) {
            System.out.println("In commondata onpostexe");**//doesn't print**
              delegate.processFinish(result);
            }
        @Override
        protected String doInBackground(String... params) {

            if (getUserData) {
                sendToServer = false;
                try {
                upd  = (UpdateData) stringToObject(resp);
                for (int i = 0; i < upd.pass.length; i++) {
                    System.out.println("upd.usn["+i+"]"+upd.usn[i]);
                    System.out.println("upd.pass["+i+"]"+upd.pass[i]);
                }**//prints fine here**
                System.out.println("in commondata resp="+resp);**//prints fine here**
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            System.out.println("resp from common return = "+resp);**//doesn't print**
            return resp;
        }
}
Mirhawk
  • 205
  • 1
  • 3
  • 14

2 Answers2

1

Although the code snippet is not optimal way of using AsyncThread, if I have to answer specific to your question then your variable is public static. Why don't you use something like following.

protected String doInBackground(String... params) {
    if (getUserData) {
        MainActivity.upd  = *data fetched from server*
    }
chejaras
  • 862
  • 5
  • 10
  • Doesn't work, I get : **"FATAL EXCEPTION: main Process: com.example.vehicle, PID: 19515 java.lang.NullPointerException: Attempt to read from null array at com.sam.MainActivity$1.onClick(MainActivity.java:70)"** At line 70 I print the data from the object. I think this is due to the async task as data is fetched after the data is printed from MainActivity. – Mirhawk Jun 24 '16 at 12:51
0

This is the best method for the thing you want to accomplish I've ever seen.

Community
  • 1
  • 1
Todor Kostov
  • 1,789
  • 1
  • 13
  • 20
  • Thanks! That's what I needed, but it doesn't seem to work properly though. I have updated the post with **Edit1**, it consists of the changes I made to My code. It seems the processFinish method in MainActivity is not reached at all as the sysout's in them don't get printed. Can You please help Me with that? – Mirhawk Jun 24 '16 at 16:48
  • Try to follow the first steps before the update part of the answer from the given link. From your edit I can see that you are using the second way. Just follow the first version step by step. – Todor Kostov Jun 25 '16 at 00:27
  • Okay , I tried following the first steps, they seemed easy. Bu it still doesn't seem to work. I have placed sysout's in multiple places to see code reach, but some of them don't print as indicated in the comments after them. Also, all the systout's in MainActivity print first and then the systout's in Async class print. – Mirhawk Jun 25 '16 at 07:18
  • Please, update your code with the last version you have or send it as a gist, so we can have a look at your latest code version. – Todor Kostov Jun 25 '16 at 07:35
  • OK, first of all in your **onClick()** method the last two print statements are executed, because the **lo.execute()** call is Asynchronous. That means the result from it can come later at any time (typical asynch. behavior). You don't see the print from **processFinish()** because in your **onClick()** you start a new activity. The current one is being destroyed by the OS and the **processFinish()** method does not exist. Try to remove the last three lines from the **onClick()** method and check the printing again. – Todor Kostov Jun 25 '16 at 10:02
  • I removed the intent code for LoginActivivty, but it still does not print the remaining sysout's. It is the same case as earlier, the one's depicted in **Edit1** with comments. Is there any way for adding a delay in MainActivity to wait till the AsyncTask finishes it's process? I know this is against the actual working process of AsyncTask, but is there any way? The code needs to be in onclick since the server address is added in MainActivity and verified in it too. – Mirhawk Jun 25 '16 at 16:45
  • Check out [link](https://gist.github.com/todorBG/12e7ced2fe1593d0f179ffdd551b9fea) This is a simple app with some random REST service based on the example I gave you earlier. It works like a charm. – Todor Kostov Jun 25 '16 at 18:23
  • Unfortunately, I cannot use REST. The rest of My project uses SOAP protocol and even though it is old, yet it would require restructuring My entire project(web service, android app). Is there no way I can implement it in the existing structure? – Mirhawk Jun 26 '16 at 07:24
  • It doesn't matter if you are using REST or SOAP with the given structure. That should not be a problem. Just replace the REST logic with SOAP. – Todor Kostov Jun 26 '16 at 07:27
  • Finally I was able to do it! Thanks a lot for the help and example! – Mirhawk Jun 28 '16 at 11:34