How get JSON data while in splash view in Android - android

Here I try to make a app.
First it shows a home page.It will display 2 sec.
Here is the code...
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int secondsDelayed = 3;
new Handler().postDelayed(new Runnable() {
public void run() {
startActivity(new Intent(MainActivity.this,SocondActivity.class));
finish();
}
}, secondsDelayed * 1000);
}
}
Then my second activity want to show a splash view until json string download from the rest service.
Here is my code....
public class SocondActivity extends Activity {
private static final String TAG = "SocondActivity";
//please assume my url is OK
private static String url = "my url";
private String jsonStr;
private final int SPLASH_DISPLAY_LENGTH = 5000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
new GetContacts().execute();
Log.d(TAG,jsonStr);
Intent mainIntent = new Intent(SocondActivity.this,
ThirdActivity.class);
SocondActivity.this.startActivity(mainIntent);
SocondActivity.this.finish();
}
}, SPLASH_DISPLAY_LENGTH);
}
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
protected Void doInBackground(Void... arg0) {
//please assume that my Server Handler class is working fine
ServiceHandler sh = new ServiceHandler();
jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
return null;
}
}
}
Then I got this error......
java.lang.NullPointerException: println needs a message
Because the jsonStr was empty....
Why is that ??
Here is my R.layout.splash_screen
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<RelativeLayout
android:id="#+id/loadingPanel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:scaleType="center"
android:src="#drawable/calendar_50" />
<ProgressBar
android:layout_below="#id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
</RelativeLayout>
</LinearLayout>
Can someone please tell me Is this method is correct and what should I change to make this correct ??

You have a race case. You need to do something like this.
Instead of utilizing a handler in onCreate like you are below (which is only serving to create a layer of complexity that isn't functioning like you expect)
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
new GetContacts().execute();
Log.d(TAG,jsonStr);
Intent mainIntent = new Intent(SocondActivity.this,
ThirdActivity.class);
SocondActivity.this.startActivity(mainIntent);
SocondActivity.this.finish();
}
}, SPLASH_DISPLAY_LENGTH);
Just call this in your onCreate()
new GetContacts().execute();
And in your AsyncTask, override the method onPostExecute like so
#Override
public void onPostExecute(Void voidParam){
Log.d(TAG,jsonStr);
Intent mainIntent = new Intent(SocondActivity.this,ThirdActivity.class);
SocondActivity.this.startActivity(mainIntent);
SocondActivity.this.finish();
}
This will tell your app that you want to execute the AsyncTask, and when you are done (and only when you are done) you want to launch your next Activity. This removes the race case as well as the need for a handler/runnable.

Related

activity to fragment method calling in a thread with progressbar

I am using this code, everything are working fine, but progressbar is not showing. I want to block my ui during the method implementation and want to show progressbar. I want to get behaviour like progressDialog.
Here is my method
public void effct(int effectNo) {
final int finalEffectNO = effectNo;
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
progressLayout.setVisibility(View.VISIBLE);
progressLayoutLinear.setVisibility(View.VISIBLE);
Thread thread = new Thread(){
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
imageViewFragment.applyEffect(finalEffectNO);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
progressLayout.setVisibility(View.GONE);
progressLayoutLinear.setVisibility(View.GONE);
}
});
}
};
thread.start();
}
My xml code for progressLayout
<LinearLayout
android:id="#+id/progressBarLinearLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/colorPrimaryDark"
android:gravity="center"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:padding="12dp"
android:visibility="gone"
android:orientation="horizontal">
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginRight="10dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Loading"
android:textColor="#FFFFFF"
android:textStyle="bold"
android:textSize="18sp"/>
</LinearLayout>
For above your requirement you must use ProgressDialog for same, here is an example
Example
Try using an AsyncTask instead of Thread, something like this :
new AsyncTask<Void, Void, Void>() {
#Override
protected void onPreExecute() {
progressLayoutLinear.setVisibility(View.VISIBLE);
}
#Override
protected Void doInBackground(final Void ... params ) {
runOnUiThread(new Runnable() {
#Override
public void run() {
imageViewFragment.applyEffect(finalEffectNO);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
}
});
return null;
}
#Override
protected void onPostExecute( final Void result ) {
progressLayoutLinear.setVisibility(View.GONE);
}
}.execute();
Hope this helps
There’s a few ways to solve your problem - check this video for more information. The most basic approach might be an AsyncTask, which could look like this:
public class DummyAsyncTask extends AsyncTask<Void, Void, Void> {
private final Window window;
private final ProgressBar progressBar;
public DummyAsyncTask(Window window, ProgressBar progressBar) {
this.window = window;
this.progressBar = progressBar;
}
#Override protected void onPreExecute() {
window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
progressBar.setVisibility(View.VISIBLE);
}
#Override protected Void doInBackground(Void... voids) {
// Do the heavy lifting.
}
#Override protected void onPostExecute(Void aVoid) {
window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
progressBar.setVisibility(View.GONE);
}
}
You execute it by running new DummyAsyncTask(/* params */).execute();.
Do note that AsyncTask does not adhere to the lifecycle and holding a reference to a Context aware instance is just asking for trouble. A safer alternative might be using LiveData:
public void effect(int effectNo) {
// Show progress and disable user interaction here.
final ListData<Content> data = model.applyEffect(effectNo);
data.observe(this, (Observer<Content>) c -> {
// Apply results, hide progress & enable user interaction.
});
}
Given the above, you should be careful how you handle showing & hiding progress, so you don’t accidentally disable user interaction forever.

ProgressBar Spinner for Async Task doesn't work

My problem is that when i click button "Click" to call my API it should show my progressBar(spinner) while I'm calling API. Instead my application freeze for less than a second and then when it's done calling it shows my loading spinner for a brief time (it just flash)
Here is my code
private ProgressBar spinner;
public View onCreateView(...)
{
spinner = (ProgressBar) view.findViewById(R.id.progressBar1);
spinner.setVisibility(View.GONE);
...
}
private class MyTask extends AsyncTask<String, Void, Void> {
String pageContent = "";
DataOutputStream wr;
#Override
protected void onPreExecute() {
spinner.setVisibility(View.VISIBLE);
}
#Override
public Void doInBackground(String... params) {
requestResult.setSuccess(false);
HttpURLConnection connection;
try {
String url = "myURL";
//I only call my Api here. I delete rest so this won't bother you
requestResult.setSuccess(true);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
JsonParser parser = new JsonParser();
//Same here i delete nonimportant
MyResponse = new Gson().fromJson(jsonContent, MyResponse.class);
done();
spinner.setVisibility(View.GONE);
}
}
I've tried hounder different things it always freeze for a second and then my loading spinner flash and my content from API is shown.
Can you help me with that one, please?
My xml file
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scroll_view_send"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<RelativeLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="25px"
android:minHeight="25px">
<ProgressBar
android:id="#+id/progressBar1"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="#id/buttonSend"
android:visibility="gone"/>
</RelativeLayout>
</ScrollView>
Try the below snippet. It does not require spinner to be declared in layout file.
AsyncTask<String, String, String> asyncObject =
new AsyncTask<String, String, String>() {
ProgressDialog progDailog;
#Override
protected void onPreExecute() {
super.onPreExecute();
progDailog =
new ProgressDialog(Activity.this);
progDailog.setMessage("Loading");
progDailog.setCancelable(false);
progDailog.show();
}
#Override
protected String doInBackground(String... urls) {
//Do background stuff here
return null;
}
#Override
protected void onPostExecute(String result) {
progDailog.cancel();
//Do post background stuff here.
}
};
asyncObject.execute(null, null, null);
Please try this working sample, pass the spinner to your MyTask like this:
private class MyTask extends AsyncTask<String, Void, Void> {
String pageContent = "";
DataOutputStream wr;
private final ProgressBar progress;
public MyTask(final ProgressBar progress) {
this.progress = progress;
}
#Override
protected void onPreExecute() {
progress.setVisibility(View.VISIBLE);
}
...
#Override
protected void onPostExecute(Void result) {
JsonParser parser = new JsonParser();
//Same here i delete nonimportant
MyResponse = new Gson().fromJson(jsonContent, MyResponse.class);
done();
progress.setVisibility(View.GONE);
}
}
Then call new MyTask(progress).execute();
EDIT: In your question you refer that your phone is freezing while calling the MyTask...
Please check this step to avoid freezing your UI in AsyncTask:
Do not call MyTask using new MyTask().get()
Try moving to doInBackground this part MyResponse = new Gson().fromJson(jsonContent, MyResponse.class); done(); this could be expensive.
Hope its helps!!

android layout not displayed

I have trouble displaying the layout of my main activity :
I create an ActivityA with an ImageView.
In onCreate(), I launch an AsyncTask, which retrieves content from Internet, and opens an ActivityB.
When I launch my application, it displays ActivityB right away.
public class ActivityA extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyTask mytask = new MyTask();
mytask.execute();
}
}
My MainActivity xml file is the following :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/loadingPanel"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/home_page"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/ic_home_page" />
<ProgressBar
android:id="#+id/marker_progress"
style="?android:attr/progressBarStyle"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="center_vertical|center_horizontal"
android:indeterminate="true" />
</RelativeLayout>
The ProgressBar is used to show the loading process of the AsyncTask.
thanks for helping
public class ActivityA extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyTask mytask = new MyTask();
mytask.execute();
}
}
private class MyTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
// code for retrieve contents from Internet
}
#Override
protected void onPostExecute(String result) {
// cancel ProgressBar and start activity B here like
Intent i = new Intent(A.this, B.class);
startActivity(i);
}
#Override
protected void onPreExecute() {
// showing ProgressBar
}
}
don't forgot to mention A activity as a launcher.
I hope it will help you to solve this problem.

How do you keep track of dependant asynchronous tasks?

I'm making an Android Application at the moment using MVC. I'm using an Activity as a Controller and a different class as the View.
The View is waiting for two asynchronous tasks, a Google Map and a task sent to fetch data from a database. The View needs the data from the database to place a marker on the map. If the map loads first the we can't place the marker. If the database task finishes then we needs to wait for the map to load.
How do I check that the dependant tasks are finished?
Should I just have a flag to say if the db task is finished and then when the map loads check this to continue and vice versa for the map.
Or is there a better way to do all this.
This is a simplified version of the View:
public class SellerAddView
implements OnChangeListener<Model>, OnMapReadyCallback{
...
public SellerAddView(View view, Model model, Activity activity){
model.addListener(this);
mapFragment = ((MapFragment)activity.getFragmentManager()
.findFragmentById(R.id.add_map));
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
LatLng coords = model.getLatLng();
map.addMarker(new MarkerOptions().position(coords));
}
#Override
public void onChange(SellerAddModel model) {
updateView();
}
}
Here is the simplified Controller:
public class Controller extends Activity{
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View screenView = View.inflate(this, activity_seller_add, null);
model = new Model();
view = new view(screenView, model, this);
populateModel();
setContentView(screenView);
}
public void populateModel(){
handler.post(new Runnable() {
#Override
public void run() {
synchronized (model) {
Model newModel = new ModelDao().getId(id);
model.consume(model);
}
}
});
}
}
So you can use the Splash screen to wait for all data to be loaded, that will be better.
Sample code as following:
public class SplashScreen extends Activity {
private static int SPLASH_DELEY = 3000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(SplashScreen.this, MainActivity.class);
startActivity(intent);
finish();
}
}, SPLASH_DELEY);
}
}
And for activity_splash_screen.xml :
<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:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.bjiang.map_ex.SplashScreen">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageLogo"
android:layout_centerInParent="true"
android:src="#drawable/splash_file"/>
</RelativeLayout>

Android: Data obtained from JSON not appearing complete in textview

In my app, I am getting text content from JSON and that content I am showing into text view. But, problem is text is not appearing complete and it is not formatted as well. I had checked my JSON using http://jsonformatter.curiousconcept.com/ and it showed the JSON is valid. I had printed the content that I received on the log and it is complete. Even, after setting it to textview and again getting back from it, I am getting complete data. But, it is not displaying complete text.
I am not getting where the problem is. The textview is inside scrollview.
Below is my code:
Base Activity
public class TIEBaseActivity extends MapActivity
{
//private ProgressDialog dialog;
public AlertDialog _alertDialog;
protected HeaderBar _headerBar;
protected FooterBar _footerBar;
protected LinearLayout _manager;
protected LinearLayout form;
protected TIEBaseActivity _self;
public void createDefaultView(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.basescreen);
this._self=this;
initView();
}
public void loadFormFromResource(int resourceID)
{
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(resourceID, null);
_manager.addView(view);
}
public void loadDefaultForm()
{
form=new LinearLayout(this);
form.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
form.setOrientation(LinearLayout.VERTICAL);
form.setGravity(Gravity.CENTER);
_manager.addView(form);
}
public void initView()
{
_headerBar = (HeaderBar) findViewById(R.id.baseHeaderBar);
_manager = (LinearLayout) findViewById(R.id.baseScrollContent);
//_footerBar = (FooterBar) findViewById(R.id.baseFooterBar);
_headerBar.view.setVisibility(View.GONE);
//_footerBar.view.setVisibility(View.GONE);
}
protected void showScreen(Intent intent) {
startActivity(intent);
}
public void setHeaderTitle(String title) {
if (_headerBar!=null) {
_headerBar.setTitle(title);
}
}
public Handler progressCloseHandler = new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (_alertDialog != null)
_alertDialog.cancel();
}
};
private Handler alertViewHandler = new Handler() {
public void handleMessage(Message msg) {
String message=(String)msg.obj;
AlertDialog.Builder _alert = new AlertDialog.Builder(TIEBaseActivity.this);
_alert.setMessage(message)
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
}
});
_alert.create().show();
}
};
public void DisplayAlert(String message) {
Message msg=Message.obtain(alertViewHandler);
msg.obj=message;
alertViewHandler.sendMessage(msg);
}
public void DisplayAlert(String message, int id) {
Message msg=Message.obtain(alertViewHandler);
msg.obj=message;
msg.what=id;
alertViewHandler.sendMessage(msg);
}
private Handler closeViewHandler=new Handler() {
public void handleMessage(Message msg) {
super.handleMessage(msg);
_self.finish();
}
};
public void closeScreen() {
closeViewHandler.sendMessage(Message.obtain(closeViewHandler));
}
public void openRating()
{
Intent marketIntent = new Intent(Intent.ACTION_VIEW,Uri.parse("market://details?id=com.dzo.tie"));
startActivity(marketIntent);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
public void openShare()
{
String mMailSubject = "OIE App. - Get the All Indian Events happening in Overseas";
String mMailMessage = null;
mMailMessage = "Hi,\n I found this great Application. This application customize for Overseas Indian Events.";
mMailMessage += "\n";
mMailMessage += "Go to: https://market.android.com/details?id=com.dzo.oie";
mMailMessage += ",\n Please visit: http://www.dotzoo.net to see more about Dotzoo Inc.";
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("text/*");
emailIntent.putExtra(Intent.EXTRA_SUBJECT, ""+mMailSubject);
emailIntent.putExtra(Intent.EXTRA_TEXT, mMailMessage);
startActivity(Intent.createChooser(emailIntent, "Share via..."));
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
}
Layout for BaseActivity:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:background="#color/white"
android:layout_height="fill_parent"
android:orientation="vertical"
android:id="#+id/baseLayout">
<com.dzo.tie.ui.HeaderBar
android:id="#+id/baseHeaderBar"
android:layout_width="fill_parent"
android:layout_height="50dp"/>
<ScrollView
android:scrollbars="vertical"
android:fillViewport="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:id="#+id/baseScrollContent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:layout_gravity="center"
android:layout_width="fill_parent">
</LinearLayout>
</ScrollView>
I am extending this base activity in my activity class:
My Activity
public class TIEInfo extends TIEBaseActivity
{
TextView txtTieInfo;
String contents;
private String infoUrl = "http://www.tradeineu.com/tie_app/aboutTie.php";
protected void onCreate(Bundle savedInstanceState)
{
super.createDefaultView(savedInstanceState);
_headerBar.view.setVisibility(View.VISIBLE);
super.setHeaderTitle("Info");
init();
new TIEInfoAsyncTask(getParent(), infoUrl, txtTieInfo).execute();
}//onCreate
public void init()
{
loadFormFromResource(R.layout.tieinfo);
txtTieInfo = (TextView)findViewById(R.id.txtTieInfo);
}//init
}//TIEInfo
Layout for my activity
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/txtTieInfo"
android:textSize="12sp"
android:textColor="#color/copper_gold"
android:lineSpacingExtra="5dp"/>
You need to scroll to see the rest of your text.
Place your textview inside a scrollView and it will be ok.

Categories

Resources