File Locking on Android Does Not Work Properly

Asked 2 years ago, Updated 2 years ago, 28 views

In order to achieve exclusive locking between Android apps, we use FileLock and FileChannel classes, but the following events have occurred in which multiple apps can acquire locks at the same time.
Could you tell me the cause?(Environment is Android 5.0.1)

public class MainActivity extensions AppCompatActivity{

    private static final String TAG = "TEST1";
    private static final String fileName=Environment.getExternalStorageDirectory().getPath()+"/testFile";
    private FileLock mFileLock;

    private Button lockBt, releaseBt;

    @ Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        lockBt=(Button) findViewById (R.id.lock_btn);
        releaseBt=(Button)findViewById(R.id.release_btn);

        lockBt.setOnClickListener(newView.OnClickListener(){
            @ Override
            public void onClick (View view) {
                while(true){
                    if(lock()){
                        break;
                    }

                    try {Thread.sleep(1000);}catch(InterruptedExceptione){};
                }
            }
        });

        releaseBt.setOnClickListener(newView.OnClickListener(){
            @ Override
            public void onClick (View view) {
                release();
            }
        });

    }

    public boolean lock() {
        if(mFileLock!=null){
            Log.d(TAG, "[lock]mFileLock is already locked.");
            return true;
        }

        FileLock fileLock=null;
        try{
            FileOutputStream fos=newFileOutputStream(newFile(fileName)));
            FileChannel fileChannel = fos.getChannel();
            fileLock = fileChannel.tryLock (0L, Long.MAX_VALUE, false);
        }catch(Exceptione){
            Log.e(TAG, e.toString());
        }

        if(fileLock==null){
            Log.e(TAG, "[lock] file lock failed.");
            return false;
        }

        Log.i(TAG, "[lock] file lock success.");
        mFileLock = fileLock;
        return true;
    }

    public void release() {
        if(mFileLock==null){
            Log.i(TAG, "[release] mFileLock is null.");
            return;
        }
        try{
            mFileLock.release();
            File file = new File(fileName);
            if(file.exists()) file.delete();
        }catch(Exceptione){
            Log.e(TAG, e.toString());
        }
        Log.i(TAG, "[release] lock released.");
        mFileLock = null;
    }
}

Run Results (logcat)

07-19 15:24:36.790 12740-12740/test.test2E/TEST2:java.io.IOException: fcntl failed:EAGAIN (Try again)
07-19 15:24:36.790 12740-12740/test.test2E/TEST2: [lock] file lock failed.
07-19 15:24:37.842 12740-12740/test.test2 E/TEST2:java.io.IOException: fcntl failed:EAGAIN (Try again)
07-19 15:24:37.842 12740-12740/test.test2 E/TEST2: [lock] file lock failed.
07-19 15:24:38.015 12692-12692/test.test1 I/TEST1: [release] lock released.
07-19 15:24:38.857 12740-12740/test.test2 I/TEST2: [lock] file lock success.
07-19 15:24:40.922 12692-12692/test.test1 I/TEST1: [lock] file lock success.

android

2022-09-29 22:41

1 Answers

I'm not looking at the source properly, so there may be other reasons, but file locking may not work in general.

(Cause と
Depending on the presence or absence of the file, the locking method may have multiple locks depending on the timing (*).
※ From making sure the file does not exist to generating the file

[Workaround]
Exclusion is managed by the presence or absence of a directory.
Create a directory for locking, lock successfully, lock everything else.


2022-09-29 22:41

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.