Friday, 29 July 2016

Glide: Caching basics

With a small reference from one of my previous blogs, Today's blog is regarding the Caching basics in Glide- Image Library.
Glide is a fast and efficient open source image loading framework for Android that wraps memory and disk caching, and resource pooling into a simple and easy to use interface.
Glide supports fetching, decoding, and displaying video stills, images, and animated GIFs.
Glide's primary focus is on making scrolling any kind of a list of images as smooth and fast as possible, but Glide is also effective for almost any case where you need to fetch, resize, and display a remote image.
With these features of glide, it also allows you to cache your images so that they can be showcased a bit faster when used frequently. But some times there is a need that you do not want to cache the images or your image URL due to some or the other reason, such as
-- Suppose the url which you are getting from your server is same but the image on that url is changed every time. In this case if the url is same then glide first check this url in its cache and if it founds that url in its cache it load the same image without requesting it again. this problem can be solved if -
I.   It is possible to always load the image from URL and not from cache. OR
II. It is possible to clear the image from cache before loading the new image from URL.

So the solution for this problem by using diskCacheStrategy() to handle the disk cache and you can skip the memory cache using skipMemoryCache() method as follows:

Glide.with(YourActivity.this)
    .load(imageURL)
    .diskCacheStrategy(DiskCacheStrategy.NONE)
    .skipMemoryCache(true)
    .into(yourImageView);

That's all.
Happy coding and remember "Code to make it better".

Friday, 22 July 2016

onScroll event of RecyclerView and Pagination

RecyclerView is the most usable view in android development due to its features and ease of usability that it provides. This post is regarding the one of the features of RecyclerView that is its ScrollEvent. If you are having thousand of records from your server, than in the case instead of requesting all the records at one time only or you can say in a single request only which will put load on your server as well as it is time consuming, you can do it in efficient way. This can be done through the addOnScrollListener in your RecyclerView. This is called Pagination. The addOnScrollListener of RecyclerView allows you to know the the last item of your data list has been reached and now you can request for new set of records. This can be implemented as follows:-

1. add the scrollListener to your recycler view as follows :-

private boolean loading = true;
int pastVisiblesItems, visibleItemCount, totalItemCount;

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() 
{
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) 
    {
        if(dy > 0) //check for scroll down
        {
            visibleItemCount = mLayoutManager.getChildCount();
            totalItemCount = mLayoutManager.getItemCount();
            pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();

            if (loading) 
            {
                if ( (visibleItemCount + pastVisiblesItems) >= totalItemCount) 
                {
                    loading = false;
                    Toast.makeText(getActivity(),"Last item reached",Toast.LENGTH_SHORT).show();
                   //here you can do the pagination code to request for new set of records
                }
            }
        }
    }
});  

2. add the new layoutmanager to your recycler view as follows:-

LinearLayoutManager mLayoutManager;
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);

That' all.. now you can scroll your recyclerview and add pagination to it.

Friday, 15 July 2016

Serializable in android

In Android we know that we cannot just pass objects to activities. The objects must either implements Serializable or Parcelable interface to do this.

Serializability of a class is enabled by the class implementing the java.io.Serializable interface. Classes that do not implement this interface will not have any of their state serialized or deserialized. All subtypes of a serializable class are themselves serializable. The serialization interface has no methods or fields and serves only to identify the semantics of being serializable.

To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype's public, protected, and (if accessible) package fields. The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class's state. It is an error to declare a class Serializable if this is not the case. The error will be detected at runtime.

During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream.

Classes that require special handling during the serialization and deserialization process must implement special methods with these exact signatures:

private void writeObject(java.io.ObjectOutputStream out)
     throws IOException
 private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException;
 private void readObjectNoData()
     throws ObjectStreamException;


The writeObject method is responsible for writing the state of the object for its particular class so that the corresponding readObject method can restore it. The default mechanism for saving the Object's fields can be invoked by calling out.defaultWriteObject. The method does not need to concern itself with the state belonging to its superclasses or subclasses. State is saved by writing the individual fields to the ObjectOutputStream using the writeObject method or by using the methods for primitive data types supported by DataOutput.

The readObject method is responsible for reading from the stream and restoring the classes fields. It may call in.defaultReadObject to invoke the default mechanism for restoring the object's non-static and non-transient fields. The defaultReadObject method uses information in the stream to assign the fields of the object saved in the stream with the correspondingly named fields in the current object. This handles the case when the class has evolved to add new fields. The method does not need to concern itself with the state belonging to its superclasses or subclasses. State is saved by writing the individual fields to the ObjectOutputStream using the writeObject method or by using the methods for primitive data types supported by DataOutput.

The readObjectNoData method is responsible for initializing the state of the object for its particular class in the event that the serialization stream does not list the given class as a superclass of the object being deserialized. This may occur in cases where the receiving party uses a different version of the deserialized instance's class than the sending party, and the receiver's version extends classes that are not extended by the sender's version. This may also occur if the serialization stream has been tampered; hence, readObjectNoData is useful for initializing deserialized objects properly despite a "hostile" or incomplete source stream.

The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException. A serializable class can declare its own serialVersionUID explicitly by declaring a field named "serialVersionUID" that must be static, final, and of type long:

ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;

If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members. Array classes cannot declare an explicit serialVersionUID, so they always have the default computed value, but the requirement for matching serialVersionUID values is waived for array classes. Android implementation of serialVersionUID computation will change slightly for some classes if you're targeting android N. In order to preserve compatibility, this change is only enabled is the application target SDK version is set to 24 or higher. It is highly recommended to use an explicit serialVersionUID field to avoid compatibility issues.

That's all. and Code to make it better.


Saturday, 9 July 2016

Runtime Permissions in android Marshmallow

Hi guys, I am back with a very important topic necessary for every android application called Run-time permission in Marshmallow. As we know that Google changed permission management in Marshmallow. So if you want your app in Marshmallow you need to handle all permission at run-time. I will not write more talking stuff so Lets start with an example of capturing an image.

Open your layout (activity_main.xml) and  add two image to it one for captured image and one for camera click.
Open your java file (MainActivity.java) and Register both imageview and add setOnClickListener to camera click imageview.
Inside onClick of camera imageview call  checkCameraPermission() method ,if permission is granted then launch camera else call  requestCameraPermission() method to open permission dialog.


Create method to launch camera.

/**
     * Method to launch camera after permission accepted from user
     */
    void takePicture() {
        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
        startActivityForResult(intent, 0);
    }


Create a method to check permission for camera as follows:

void checkCameraPermission() {
        boolean isGranted;
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            // Camera permission has not been granted.
                requestCameraPermission();
} else {
               takePicture();
        }
    }


Implement ActivityCompat.OnRequestPermissionsResultCallback in MainActivity as:

public class MainActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback



Override onRequestPermissionResult() method.
Inside onRequestPermissionResult() check permission, if it is granted then launch camera else show a Toast.

@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == REQUEST_CAMERA) {
            // BEGIN_INCLUDE(permission_result)
            // Received permission result for camera permission.
            Log.i(TAG, "Received response for Camera permission request.");

            // Check if the only required permission has been granted
            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // Camera permission has been granted, preview can be displayed

                takePicture();

            } else {
              //Permission not granted
                Toast.makeText(MainActivity.this,"You need to grant camera permission to use camera",Toast.LENGTH_LONG).show();
            }

        }
    }



Override onActivityResult() method to get image from camera and set it to imageview.

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

            if (resultCode == Activity.RESULT_OK && requestCode == 0) {

            //this is your bitmap image and now you can do whatever you want with this

            Bitmap picture = (Bitmap) data.getExtras().get("data");

            iv_pic.setImageBitmap(picture);
         }
    }

That's all. and if still have any problem feel free to comment below.
Happy coding and remember, Code to make it better!!