How to call Android layout in Unity? - android

I am finding the solution of my problem but not satisfied from all of them.
I create an android library which shows a ad view layout witch is and know I want to call this layout in unity but can't find any solution please anyone help me how can I call my layout in unity?
public class RedeemLayout extends LinearLayout implements View.OnClickListener,HttpCallBacks {
public Dialog dialogBox;
public ImageButton close;
public ImageView advert;
public TextView location_text;
TextView tv_massagetext;
EditText et_redeemdetial;
Button btn_redem;
ImageButton btn_closead;
DeviceInfo device = new DeviceInfo();
String adClickUrl;
HttpNetworkCalls httpNetworkCalls;
Context context;
Activity activity;
ImageView bmImage;
FrameLayout redeemLayout;
AdInfo ad;
private AdInfo adInfo;
private UserInfo user;
public RedeemLayout(Context context) {
super(context);
initialize(context);
this.context = context;
}
public RedeemLayout(Activity activity, Context context) {
super(context);
initialize(context);
this.context = context;
this.activity = activity;
}
public RedeemLayout(Context context, AttributeSet attr) {
super(context, attr);
initialize(context);
this.context = context;
}
private void initialize(Context context) {
inflate(context, R.layout.ad_lyout, this);
tv_massagetext = (TextView) findViewById(R.id.massagetext);
et_redeemdetial = (EditText) findViewById(R.id.redeemdetail);
btn_redem = (Button) findViewById(R.id.btn_redeem);
btn_closead = (ImageButton) findViewById(R.id.btn_CloseFullScreenAd);
bmImage = (ImageView) findViewById(R.id.adimage);
redeemLayout = (FrameLayout) findViewById(R.id.redeemLayout);
httpNetworkCalls = new HttpNetworkCalls(this);
btn_redem.setOnClickListener(this);
btn_closead.setOnClickListener(this);
DownloadAdAccordingToLocation();
}
public void onClick(View view) {
int i = view.getId();
if (i == R.id.btn_redeem) {
Toast.makeText(getContext(), "Thanks for Redeem You will get Massage soon...", Toast.LENGTH_LONG).show();
Map<String, String> data = new HashMap<>();
data.put("ad_id",ad.getAdId());
data.put("app_id","1");
data.put("location","lahore");
data.put("session","1");
try {
httpNetworkCalls.post(data, API.UPDATE_IMPRESSIONS);
// call AsynTask to perform network operation on separate thread
} catch (Exception e) {
e.printStackTrace();
}
// call AsynTask to perform network operation on separate thread
}
if (i == R.id.btn_CloseFullScreenAd) {
redeemLayout.removeAllViews();
redeemLayout.setVisibility(View.GONE);
Map<String, String> data = new HashMap<>();
data.put("ad_id",ad.getAdId());
data.put("app_id","1");
data.put("location","lahore");
data.put("session","1");
Toast.makeText(getContext(), "Thanks for Redeem You will get Massage soon...", Toast.LENGTH_LONG).show();
try {
httpNetworkCalls.post(data, API.UPDATE_IMPRESSIONS);
// call AsynTask to perform network operation on separate thread
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void DownloadAdAccordingToLocation() {
try {
httpNetworkCalls.get(API.RANDOM_ADVERTISEMENT);
} catch (IOException e) {
e.printStackTrace();
}
}
public void adButtonClicked(View v) {
// FullScreenAdDialog db = new FullScreenAdDialog(this, ad, updateAdClick);
// db.show();
// Intent x = new Intent(xcontext, AdActivity.class);
// x.putExtra("image_link", ad.getImage_link());
// x.putExtra("url", ad.getUrl());
// x.putExtra("adid", ad.getAdId());
// x.putExtra("adclickurl", updateAdClick);
// startActivity(x);
}
#Override
public void HttpResponse(final int apiCode, final JSONObject response, final boolean isSuccess) {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
try {
if (apiCode == API.RANDOM_ADVERTISEMENT) {
if (response.has("networkError")) {
Log.e("Error", response.getString("networkError"));
} else {
ad = AdInfo.fromJson(response);
if (ad.isSuccess()) {
Picasso.Builder builder = new Picasso.Builder(context);
builder.listener(new Picasso.Listener() {
#Override
public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
redeemLayout.removeAllViews();
redeemLayout.setVisibility(View.GONE);
}
});
Picasso pic = builder.build();
pic.load(ad.getImage_url()).into(bmImage);
// Picasso.with(context)
// .load(ad.getImage_url())
// .error(R.drawable.imagecross)
// .into(bmImage);
} else {
Log.e("Error", response.getString("parseError"));
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
and call my library in android app like this.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout layout= (RelativeLayout)findViewById(R.id.test);
RedeemLayout redeemLayout= new RedeemLayout(this, this);
redeemLayout.setGravity(Gravity.CENTER);
layout.addView(redeemLayout);
}
}

It's more unity3d question. You cannot call your layout directly, you can only send message to android code. Read Unity3d script documentation (or google for code) of AndroidJavaClass and AndroidJavaObject.
From Android perspective I think that you should implement some kind of static method that you can call from unity and it should broadcast or send event in event bus that will be handled by your advertisement engine.
Unity part of code should be similar to this:
AndroidJavaClass javaClass = new AndroidJavaClass("com.mypackage.MyClassWithMyStaticMethod");
javaClass.getStatic<AndroidJavaObject>("MyStaticMethod", 42);
Android MyClassWithMyStaticMethod class should implement:
public static void MyStaticMethid(int param) {...}
Check this doc: AndroidJavaClass

Related

Android setText inside AsyncTask has no effect on the UI

I have a problem related to AsyncTask. I want to change the text inside the onPostExecute method, but it doesn't work. I really don't know what I am doing wrong. Can somebody help me out please?
I don't understand why it work when I declare the AsyncTask as a nested class but it don't work when I declare it as a own class.
Here is my code:
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button button = null;
private Helper helper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.helper = new Helper(this, getLayoutInflater());
this.button = (Button) findViewById(R.id.button1);
this.button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
new MyAsyncTask(helper).execute("");
} catch (Exception e) {
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
}
}
});
}
}
Helper.java
public class Helper {
private Context context;
private LayoutInflater inflater;
public Helper(Context context, LayoutInflater inflater) {
setContext(context);
setInflater(inflater);
}
public Context getContext() {
return context;
}
public void setContext(Context context) {
this.context = context;
}
public LayoutInflater getInflater() {
return inflater;
}
public void setInflater(LayoutInflater inflater) {
this.inflater = inflater;
}
}
MyAsyncTask.java
public class MyAsyncTask extends AsyncTask<String, String, String> {
private Helper helper;
public MyAsyncTask(Helper helper) {
setHelper(helper);
}
public String getJSON(String url, int timeout) {
HttpURLConnection c = null;
try {
URL u = new URL(url);
c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setRequestProperty("Content-length", "0");
c.setUseCaches(false);
c.setAllowUserInteraction(false);
c.setConnectTimeout(timeout);
c.setReadTimeout(timeout);
c.connect();
int status = c.getResponseCode();
switch (status) {
case 200:
case 201:
BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
return sb.toString();
}
} catch (MalformedURLException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} finally {
if (c != null) {
try {
c.disconnect();
} catch (Exception ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
}
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String s) {
TextView t = (TextView) getHelper().getInflater().inflate(R.layout.activity_main, null).findViewById(R.id.textView);
t.setText("" + s); //has no effect on the UI but the text was set????
Toast.makeText(getHelper().getContext(), t.getText(), Toast.LENGTH_LONG).show();
super.onPostExecute(s);
}
#Override
protected String doInBackground(String... params) {
return getJSON("testside.com", 10000);
}
public Helper getHelper() {
return helper;
}
public void setHelper(Helper helper) {
this.helper = helper;
}
}
Thanks :)
Utilize you AsyncTask outside of your main Class using separate files
class MyActivity{
new MyAsyncTask().execute();
}
Your AsyncTask lives as another class Extending AsyncTask
class MyAsyncTask extends AsyncTask{
public MyAsyncTask(Context appContext){
}
}
Be sure to pass in your App's Context. You can only execute each instance of the task once.... but you can create and run a new instance when needed...
Wouldn't fly:
class MyActivity{
MyAsyncTask myTask = new MyAsyncTask();
myTask.execute();
//DO OTHER STUFF
myTask.execute();
}
You would instead do each time needed:
new MyAsyncTask().execute();
Your code looks fine but it doesn't work because it take reference to TextView from new layou which you inflate.
You have two options:
In your helper store TextView which you want to change, you can make it optional if your helper looks something like this:
public class Helper {
private Context context;
private LayoutInflater inflater;
private TextView textView;
...
public void addTextView(TextView textView){
this.texView = textView;
}
public TextView getTextView(){
return textView;
}
}
and then in your postExecute() call TextView t = helper.getTextview().
Pass textView directly to your AsyncTask so it look like
public MyAsyncTask(Helper helper, TextView t) {
setHelper(helper);
this.textView = t;
}
Your AsyncTask is executed on a background thread. To update your UI call,
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText("Text");
}
});
on an activity.

How to implement ondraw after httprequest to database

I'm new on Android development and I have been struggling on how to draw some graphics after a HTTP request to a Mysql database. I have looked into SyncTask, custom View and onDraw method but I must be missing something because I just can't get it to work. Basically the http request selects some records from the db (I got that working) and I need to create a graph with the data. The http request is an asynchronous process so by the time the http request is done, the onDraw method got executed with no data, that's why I started looking into SyncTask but I can't manage to pass the array that stores the data to be drawn from the onPostExecute method. Any help would be greatly appreciated and if you can point to some sample code that would be great. Thank you
Here is some code that I found online and I have been trying to make it work, so far I can get the data, to simplify it I'm only working with the field location, and I want to drawtext location:
public class TestFragment extends Fragment {
private static final String TAG = "AsyncTestFragment";
// get some fake data
private static final String TEST_URL = "http://jsonplaceholder.typicode.com/comments";
//private static final String TEST_URL = "http://localhost/~juan/A_get_tanks.php";
private static final String ACTION_FOR_INTENT_CALLBACK = "THIS_IS_A_UNIQUE_KEY_WE_USE_TO_COMMUNICATE";
ProgressDialog progress;
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_test, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getContent();
}
private void getContent() {
// the request
try {
HttpGet httpGet = new HttpGet(new URI(TEST_URL));
RestTask task = new RestTask(getActivity(), ACTION_FOR_INTENT_CALLBACK);
task.execute(httpGet);
progress = ProgressDialog.show(getActivity(), "Getting Data ...", "Waiting For Results...", true);
}
catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
#Override
public void onResume() {
super.onResume();
getActivity().registerReceiver(receiver, new IntentFilter(ACTION_FOR_INTENT_CALLBACK));
}
#Override
public void onPause() {
super.onPause();
getActivity().unregisterReceiver(receiver);
}
/**
* Our Broadcast Receiver. We get notified that the data is ready, and then we
* put the content we receive (a string) into the TextView.
*/
public BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String location;
// clear the progress indicator
if (progress != null) {
progress.dismiss();
}
String response = intent.getStringExtra(RestTask.HTTP_RESPONSE);
try {
JSONObject mainObject = new JSONObject(response);
JSONArray tank_data = mainObject.getJSONArray("tank_data");
JSONObject tankObj = tank_data.getJSONObject(0);
location = (String) tankObj.getString("Location");
} catch (JSONException e) {
location = null;
e.printStackTrace();
}
new TankView(context, location);
Log.i(TAG, "RESPONSE = " + location);
}
};
}
public class RestTask extends AsyncTask<HttpUriRequest, Void, String>
{
private static final String TAG = "AsyncRestTask";
public static final String HTTP_RESPONSE = "httpResponse";
private Context mContext;
private HttpClient mClient;
private String mAction;
public RestTask(Context context, String action) {
mContext = context;
mAction = action;
mClient = new DefaultHttpClient();
}
public RestTask(Context context, String action, HttpClient client) {
mContext = context;
mAction = action;
mClient = client;
}
#Override
protected String doInBackground(HttpUriRequest... params) {
try {
HttpUriRequest request = params[0];
HttpResponse serverResponse = mClient.execute(request);
BasicResponseHandler handler = new BasicResponseHandler();
return handler.handleResponse(serverResponse);
}
catch (Exception e) {
// TODO handle this properly
e.printStackTrace();
return "";
}
}
#Override
protected void onPostExecute(String result) {
Log.i(TAG, "RESULT = " + result);
Intent intent = new Intent(mAction);
intent.putExtra(HTTP_RESPONSE, result);
// broadcast the completion
mContext.sendBroadcast(intent);
}
}
package com.alvinalexander.asynctest;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
public class TestActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
TestFragment testFragment = new TestFragment();
getFragmentManager().beginTransaction().add(android.R.id.content, testFragment).commit();
setContentView(new TankView(this, ""));
}
}
}
public class TankView extends View {
private String location;
private Paint _paintTank = new Paint();
public TankView(Context context, String location) {
super(context);
// TODO Auto-generated constructor stub
init(null, 0);
this.location = location;
}
public TankView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
init(attrs, 0);
}
public TankView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init(attrs, 0);
}
public TankView(TestActivity testActivity, String location) {
super(testActivity);
this.location = location;
}
public TankView(TestActivity testActivity, Object o) {
super(testActivity, (AttributeSet) o);
}
private void init(AttributeSet attrs, int defStyle) {
_paintTank.setColor(Color.RED);
_paintTank.setAntiAlias(true);
_paintTank.setStyle(Paint.Style.STROKE);
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (this.location != null) {
canvas.drawText(this.location, 10, 10, _paintTank);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:background="#AEECFF">
<!-- fill the screen with a textview. the app will write text into it. -->
<com.alvinalexander.asynctest.TankView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>

Activity is starting slowly

There are several buttons in my app. New activity starts quickly whenever i press any button except for one. It lags to open a new activity.Why it is lagging ?
Here is the code snipet :
Intent intent = new Intent(this, ChooseActivity.class);
startActivityForResult(intent, Constant.MP_REQUEST);
ChooseActivity.class:
ChooseActivityHelper mActivityHelper;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
mActivityHelper = new ChooseActivityHelper(this);
mActivityHelper.inflateView();
}
ChooseActivityHelper:
public ChooseActivityHelper(Context ctx) {
mCurrentTabIndex = 1;
mContext = ctx;
}
// inflate data to view
#SuppressLint("UseSparseArrays")
public void inflateView() {
ChooseActivity act = (ChooseActivity) mContext;
try {
assMngr = act.getAssets();
String[] folders = assMngr.list(Constant._FOLDER);
for (String f : folders) {
inflateTabView(f);
stampFolderList.add(f);
}
} catch (IOException e) {
e.printStackTrace();
}
}

Call method of interface implements with child fragment From container activity Android

I'm stuck with communication between activity and fragment using interface. I have created activity with child fragment. I wanna do some stuff with continuous thread defined in activity and during that thread when I'm getting some result at that time I wanna trigger to child fragment to do something.
My Container Activity
public class MySpaceActivity extends BaseDrawerActivity {
private OnSetLastSeenListener mListner;
public static Thread mThread = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setHeaders(Const.MY_SPACE);
super.setSubmenus(Const.MY_SPACE,
Utils.getSubmenuList(Const.MY_SPACE, MySpaceActivity.this),
submenuBean);
// super.attachFragment(submenuBean);
}
#Override
public void setHeaderSubMenu(SubmenuBean subMenuBean) {
// txt_submenu.setText(subMenuBean.getSubmenu_name());
this.submenuBean = subMenuBean;
Log.print("::::: setHeaderSubMenu ::::");
super.attachFragment(submenuBean);
}
public void setsubFragment(SubmenuBean subMenuBean) {
this.submenuBean = subMenuBean;
super.attachSubFragment(submenuBean);
}
#Override
public void onBackPressed() {
super.onBackPressed();
popLastFragment();
}
private void popLastFragment() {
if (super.getNumberOfChilds() > 1) {
super.popSubFragment();
} else {
finish();
}
}
#Override
protected Fragment getFragement() {
StudentsFragment fragment = new StudentsFragment(Const.MY_SPACE,
getSubmenubean());
return fragment;
}
public SubmenuBean getSubmenubean() {
return submenuBean;
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
mThread = new Thread(new CountDownTimer(MySpaceActivity.this));
mThread.start();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
if (mThread.isAlive()) {
mThread.interrupt();
mThread = null;
}
}
public void updateLastSeen(){
Log.print("::::::Call Interface::::::");
mListner.updateLastSeen();
}
class CountDownTimer implements Runnable {
private Context mContext;
private JSONObject mJsonObject;
private JSONArray mJsonArray;
public CountDownTimer(Context mContext) {
this.mContext = mContext;
}
// #Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
HttpChatLastSeen mChat = new HttpChatLastSeen();
mJsonObject = mChat.Http_ChatLastSeen(mContext);
String mResult = mJsonObject.getString("Result");
if (mResult.equalsIgnoreCase(String
.valueOf(Const.RESULT_OK))) {
mJsonArray = mJsonObject.getJSONArray("UserData");
for (int i = 0; i < mJsonArray.length(); i++) {
mJsonObject = mJsonArray.getJSONObject(i);
new DbStudentMasterBll(mContext).update(
"last_seen", mJsonObject
.getString("LastSeen"), Integer
.parseInt(mJsonObject
.getString("UserId")));
}
} else {
Log.print("MY LAST SEEN Response : "
+ mJsonObject.toString());
}
updateLastSeen();
Thread.sleep(15000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (Exception e) {
Log.print("ChatLastSeenThread : ", e.getMessage());
}
}
}
}
}
My Child Fragment With Interface :
public class StudentsFragment extends Fragment implements OnSetLastSeenListener{
TextView txt_submenu;
ListView list_students;
SubmenuBean submenuBean;
int Mainmenu;
MySpaceActivity mMySpaceActivity;
ArrayList<DbStudentMasterBean> studentsList;
StudentsAdapter mAdapter = null;
OnSetLastSeenListener mListner;
public StudentsFragment() {
super();
}
public StudentsFragment(int Mainmenu, SubmenuBean submenuBean) {
this.submenuBean = submenuBean;
this.Mainmenu = Mainmenu;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_students, container,
false);
mMySpaceActivity = (MySpaceActivity) getActivity();
txt_submenu = (TextView) view.findViewById(R.id.txt_submenu);
txt_submenu.setText(submenuBean.getSubmenu_name());
txt_submenu.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
mMySpaceActivity.openDrawer();
}
});
list_students = (ListView) view.findViewById(R.id.list_colleagues);
studentsList = new DbStudentMasterBll(getActivity()).getAllRecords();
mAdapter = new StudentsAdapter(getActivity(), studentsList, handler);
list_students.setAdapter(mAdapter);
list_students.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
DbStudentMasterBean bean = (DbStudentMasterBean) parent
.getAdapter().getItem(position);
Message msg = new Message();
msg.what = CHAT;
msg.obj = bean;
handler.sendMessage(msg);
}
});
return view;
}
Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case CHAT:
submenuBean.setTag(VIEWCHATSTUDENT);
DbStudentMasterBean bean = (DbStudentMasterBean) msg.obj;
mMySpaceActivity.setsubFragment(submenuBean);
break;
}
};
};
#Override
public void updateLastSeen() {
// TODO Auto-generated method stub
Log.print("!!!!!!!!!Refresh Adapter!!!!!!!!!!!");
mAdapter.notifyDataSetChanged();
}
}
My Interface :
public interface OnSetLastSeenListener {
public void updateLastSeen();
}
So I have implemented interface OnSetLastSeenListener with my child fragment StudentsFragment . Now I'm calling method of tht interface updateLastSeen() from my container activity with thread. But it is not getting trigger to child fragment where I have implemented interface. So I don't know whether it is good way to communicate or not? Let me take your help to suggest on this solution or best way to communicate from child fragment to parent activity.
Thanks,
It is better to use interface when you want to communicate something from Fragment to Activity and not vice versa.
In your case, you can directly call the method in Fragment from Activity through fragment object. No need to use interface.
Something like this (For static fragments)
StudentsFragment fragment = (StudentsFragment) getFragmentManager()
.findFragmentById(R.id.fragmentid);
if (fragment != null && fragment.isInLayout()) {
fragment.updateLastSeen();
}
For dynamic fragment you can use the fragment object directly.

Android - progressdialog not displaying in AsyncTask

I have an android app that I am having trouble with.
Basically the ProgressDialog is not showing at all. I believe this to be a threading issue of some sort but I don't know how to fix it.
I am using ActionBarSherlock with some Fragments. I am also using the new Android DrawerLayout where I have my options on the drawer, which replace a fragment when clicked.
On first load of my app, I want to check the database to see if the inital data has been downloaded. If not, then I go off and begin an AsyncTask to download the data. This SHOULD have a ProgressDialog display during this, but it doesnt.
Can someone see where I am going wrong? Thanks.
MainScreen - The default landing page/fragment when the app opens
public class MainScreen extends SherlockFragment {
public static final String TAG = "MainScreen";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_main, container, false);
setHasOptionsMenu(false);
ImageView imgLogo = (ImageView) rootView.findViewById(R.id.imgMainScreen);
imgLogo.setOnClickListener(new ButtonHandler(getActivity()));
checkDatabase();
return rootView;
}
private void checkDatabase() {
//Ensure there is data in the database
DBHelper db = new DBHelper(this.getSherlockActivity());
db.checkDatabase();
}
...
}
DBHelper.checkDatabase() - The method that initiates the download
public void checkDatabase() {
if (isEmpty()) {
//Connect to net and download data
NetworkManager nm = new NetworkManager(activity);
if (!nm.downloadData()) {
Toast.makeText(activity, R.string.internetCheck, Toast.LENGTH_SHORT).show();
}
}
}
and finally
NetworkManager.downloadData() - The method that kicks off the AsyncTask:
public boolean downloadData() {
try {
return new HttpConnection(activity).execute().get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
return false;
}
public class HttpConnection extends AsyncTask<Void, Void, Boolean> {
private ProgressDialog progressDialog;
private Activity m_activity;
protected HttpConnection(Activity activity) {
m_activity = activity;
}
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(m_activity);
progressDialog.setMessage("Wait ...");
progressDialog.setCancelable(false);
progressDialog.setMax(100);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.show();
super.onPreExecute();
}
#Override
protected Boolean doInBackground(Void... params) {
String[] types = new String[]{"type1", "type2", "type3", "type4", };
StringBuilder sb = new StringBuilder();
for(String type : types) {
sb = new StringBuilder();
if(DBHelper.TYPE4_TABLE.equals(type)) {
InputStream is = activity.getResources().openRawResource(R.raw.dbdata);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
try {
sb.append(reader.readLine());
} catch (IOException e) {
Toast.makeText(activity.getApplicationContext(), "Error retriveving data", Toast.LENGTH_SHORT).show();
Log.e(Constants.TAG, "Error reading data");
e.printStackTrace();
}
} else {
sb = fetchURLData(Constants.ALL_URL+type);
}
cleanDataAndStore(sb, type);
}
return true;
}
#Override
protected void onPostExecute(Boolean result){
progressDialog.hide();
}
}
Using the above code, all I get is a white screen as the app tries to load, and sometimes an ANR. When the download is done, the fragment loads. So it works fine except for the missing ProgressDialog.
PS, Notice I'm setting the activity in each constructor.
Thanks.
Remove .get() from return new HttpConnection(activity).execute().get(); You are basically locking your UI thread. Once removed it should work as AsyncTasks are expected to work.
The purpose is to be Asynchronous so boolean downloadData() should have a return type of void. If you need to do something with the data then you should implement an interface "listener" and pass it to the AsyncTask.
Example Listener:
class TaskConnect extends AsyncTask<Void, Void, ConnectionResponse> {
private final AsyncTaskListener mListener;
/**
*
*/
public TaskConnect(AsyncTaskListener listener) {
...
mListener = listener;
}
#Override
protected void onPreExecute() {
if (mListener != null) {
mListener.onPreExecute(mId);
}
}
#Override
protected ConnectionResponse doInBackground(Void... cData) {
...
return responseData;
}
#Override
protected void onPostExecute(ConnectionResponse response) {
if (mListener != null) {
mListener.onComplete(response);
} else {
LOG.w("No AsyncTaskListener!", new Throwable());
}
}
}
public interface AsyncTaskListener {
public abstract void onPreExecute(int id);
public abstract void onComplete(ConnectionResponse response);
}
My issue was not the common issue of others where they were calling get() method after execute() method. My issue was the Context I was passing to my AsyncTask method. I have a settingsActivity and I have a ReadMeActivity that calls the asynctask task. Instead of using the context in which is was being called (ReadMeActivity.this) I used the settingsActivity which prevented it from being seen. Once I switched it and passed it the context in which the activity was being called it worked.
Hope it helps someone else.

Categories

Resources