Deleting an object in java?
didn’t work. EDIT: Okay, I’ll give some more context. I’m making a small game with a oval you can control, and a oval which follows you. Now I’ve got files named: DrawPanel.class, this class draws everything on the screen, and handles collisions, sounds, etc. I got an enemy.class, which is the oval following the player. I got an entity.class, which is the player you can control. And if the player intersects with the follower, I want my player object to get deleted. The way I’m doing it:
public void checkCollisions() < if(player.getBounds().intersects(follower1.getBounds()))< Follower1Alive = false; player.health = player.health - 10; >>
There is no deletion of objects in Java. But you normally don’t need to: what you need is to make sure there is nothing shown at screen anymore (if this is what «following you» is doing).
Perhaps you want to try and force garbage collector to remove an object? there is a question about it here already. Or perhaps you trying something else? you can try reading a bit about the garbage collector here or here If its still no help, you will need to be more specific.
If you really really really want to handle object allocations manually, use JNI: create a C/C++ lib which is used from Java code but does everything (create, delete, etc.) on it’s own — but inside your lib you have C/C++ code, no Java. I’ve not seen any way to delete a Java object manually. If your profiler tells you that there are problems, these problems often base on «forgotten» references to objects. In your case there does not seem to be a problem anywhere.
7 Answers 7
You should remove the references to it by assigning null or leaving the block where it was declared. After that, it will be automatically deleted by the garbage collector (not immediately, but eventually).
Object a = new Object(); a = null; // after this, if there is no reference to the object, // it will be deleted by the garbage collector
if (something) < Object o = new Object(); >// as you leave the block, the reference is deleted. // Later on, the garbage collector will delete the object itself.
Not something that you are currently looking for, but FYI: you can invoke the garbage collector with the call System.gc()
Having to manually call System.gc() is generally not a good idea, since it may actually be ignored by the JVM.
Not a good idea, but you can also call similar to System.. Runtime.getRuntime().gc(). More Info:he garbage collection routines that Java provides are members of the Runtime class. The Runtime class is a special class that has a single object (a Singleton) for each main program. The Runtime object provides a mechanism for communicating directly with the virtual machine. To get the Runtime instance, you can use the method Runtime.getRuntime(), which returns the Singleton.
Is null assignment a definite sign to the GC that this object is to be Garbaged Cleaned in the next GC invocation?* Assigning null to collection objects (Lists, Arrays) marks them for cleaning? stackoverflow.com/questions/449409/…
There is no guarantee that the garbage collector will ever run, or that, if it does, it will collect (not ‘delete’) any specific object.
There is no delete in java, and all objects are created on the heap. The JVM has a garbage collector that relies on reference counts.
Once there are no more references to an object, it becomes available for collection by the garbage collector.
myObject = null may not do it; for example:
Foo myObject = new Foo(); // 1 reference Foo myOtherObject = myObject; // 2 references myObject = null; // 1 reference
All this does is set the reference myObject to null, it does not affect the object myObject once pointed to except to simply decrement the reference count by 1. Since myOtherObject still refers to that object, it is not yet available to be collected.
Clear Application’s Data Programmatically
I want to clear my application’s data programmatically. Application’s data may contain anything like databases, shared preferences, Internal-External files or any other files created within the application. I know we can clear data in the mobile device through:
6 Answers 6
I highly recommend using it in new applications:
import android.os.Build.*; if (VERSION_CODES.KITKAT else < // use old hacky way, which can be removed // once minSdkVersion goes above 19 in a few years. >
If you don’t want the hacky way you can also hide the button on the UI, so that functionality is just not available on old phones.
Knowledge of this method is mandatory for anyone using android:manageSpaceActivity .
Whenever I use this, I do so from a manageSpaceActivity which has android:process=»:manager» . There, I manually kill any other processes of my app. This allows me to let a UI stay running and let the user decide where to go next.
private static void killProcessesAround(Activity activity) throws NameNotFoundException < ActivityManager am = (ActivityManager)activity.getSystemService(Context.ACTIVITY_SERVICE); String myProcessPrefix = activity.getApplicationInfo().processName; String myProcessName = activity.getPackageManager().getActivityInfo(activity.getComponentName(), 0).processName; for (ActivityManager.RunningAppProcessInfo proc : am.getRunningAppProcesses()) < if (proc.processName.startsWith(myProcessPrefix) && !proc.processName.equals(myProcessName)) < android.os.Process.killProcess(proc.pid); >> >
It has to kill the app, or else it could have data it is holding on to that will get written back. The only safe way to do this is to (1) kill the app, (2) clear all of its data, (3) next time the app starts up it will start fresh with no data.
Hi @TWiStErRob I want to implement this method when clicked on LOGOUT button in my application. But it force closes the app. Instead I want to start the main activity where the signup/sign in form is present.. How will this be possible?
I’m just putting the tutorial from the link ihrupin posted here in this post.
package com.hrupin.cleaner; import java.io.File; import android.app.Application; import android.util.Log; public class MyApplication extends Application < private static MyApplication instance; @Override public void onCreate() < super.onCreate(); instance = this; >public static MyApplication getInstance() < return instance; >public void clearApplicationData() < File cacheDirectory = getCacheDir(); File applicationDirectory = new File(cacheDirectory.getParent()); if (applicationDirectory.exists()) < String[] fileNames = applicationDirectory.list(); for (String fileName : fileNames) < if (!fileName.equals("lib")) < deleteFile(new File(applicationDirectory, fileName)); >> > > public static boolean deleteFile(File file) < boolean deletedAll = true; if (file != null) < if (file.isDirectory()) < String[] children = file.list(); for (int i = 0; i < children.length; i++) < deletedAll = deleteFile(new File(file, children[i])) && deletedAll; >> else < deletedAll = file.delete(); >> return deletedAll; > >
So if you want a button to do this you need to call MyApplication.getInstance(). clearApplicationData() from within an onClickListener
Update: Your SharedPreferences instance might hold onto your data and recreate the preferences file after you delete it. So your going to want to get your SharedPreferences object and
You need to add android:name=»your.package.MyApplication» to the application tag inside AndroidManifest.xml if you had not done so. Else, MyApplication.getInstance() returns null , resulting a NullPointerException.
Удалить данные приложения java
Продолжим работу с проектом из прошлой темы, где мы получаем данные. Теперь добавим в него стандартную CRUD-логику (создание, обновление, удаление).
Чтобы не нагромождать форму с главной activity, все остальные действия по работе с данными будут происходить на другом экране. Добавим в проект новый класс activity, который назовем UserActivity:
В файле activity_user.xml определим универсальую форму для добавления/обновления/удаления данных:
И также изменим код UserActivity :
package com.example.sqliteapp; import androidx.appcompat.app.AppCompatActivity; import android.content.ContentValues; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; public class UserActivity extends AppCompatActivity < EditText nameBox; EditText yearBox; Button delButton; Button saveButton; DatabaseHelper sqlHelper; SQLiteDatabase db; Cursor userCursor; long userId=0; @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_user); nameBox = findViewById(R.id.name); yearBox = findViewById(R.id.year); delButton = findViewById(R.id.deleteButton); saveButton = findViewById(R.id.saveButton); sqlHelper = new DatabaseHelper(this); db = sqlHelper.getWritableDatabase(); Bundle extras = getIntent().getExtras(); if (extras != null) < userId = extras.getLong("id"); >// если 0, то добавление if (userId > 0) < // получаем элемент по id из бд userCursor = db.rawQuery("select * from " + DatabaseHelper.TABLE + " where " + DatabaseHelper.COLUMN_ID + "=?", new String[]); userCursor.moveToFirst(); nameBox.setText(userCursor.getString(1)); yearBox.setText(String.valueOf(userCursor.getInt(2))); userCursor.close(); > else < // скрываем кнопку удаления delButton.setVisibility(View.GONE); >> public void save(View view) < ContentValues cv = new ContentValues(); cv.put(DatabaseHelper.COLUMN_NAME, nameBox.getText().toString()); cv.put(DatabaseHelper.COLUMN_YEAR, Integer.parseInt(yearBox.getText().toString())); if (userId >0) < db.update(DatabaseHelper.TABLE, cv, DatabaseHelper.COLUMN_ID + "=" + userId, null); >else < db.insert(DatabaseHelper.TABLE, null, cv); >goHome(); > public void delete(View view)< db.delete(DatabaseHelper.TABLE, "_id = ?", new String[]); goHome(); > private void goHome() < // закрываем подключение db.close(); // переход к главной activity Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(intent); >>
При обновлении или удалении объекта из списка из главной activity в UserActivity будет передаваться id объекта:
long userId=0; //. Bundle extras = getIntent().getExtras(); if (extras != null)
Если из MainActivity не было передано id, то устанавливаем его значение 0, следовательно, у нас будет добавление, а не редактирование/удаление
Если id определен, то получаем по нему из базы данных объект для редактирования/удаления:
if (id < 0) < userCursor = db.rawQuery("select * from " + DatabaseHelper.TABLE + " where " + DatabaseHelper.COLUMN_ID + "=?", new String[]); userCursor.moveToFirst(); nameBox.setText(userCursor.getString(1)); yearBox.setText(String.valueOf(userCursor.getInt(2))); userCursor.close(); >
Иначе просто скрываем кнопку удаления.
Для выполнения операций по вставке, обновлению и удалению данных SQLiteDatabase имеет методы insert() , update() и delete() . Эти методы вызываются в обработчиках кнопок:
db.delete(DatabaseHelper.TABLE, "_id = ?", new String[]);
В метод delete() передается название таблицы, а также столбец, по которому происходит удаление, и его значение. В качестве критерия можно выбрать несколько столбцов, поэтому третьим параметром идет массив. Знак вопроса ? обозначает параметр, вместо которого подставляется значение из третьего параметра.
ContentValues
Для добавления или обновления нам надо создать объект ContentValues . Данный объект представляет словарь, который содержит набор пар «ключ-значение». Для добавления в этот словарь нового объекта применяется метод put . Первый параметр метода — это ключ, а второй — значение, например:
ContentValues cv = new ContentValues(); cv.put("NAME", "Tom"); cv.put("YEAR", 30);
В качестве значений в метод put можно передавать строки, целые числа, числа с плавающей точкой
В данном же случае добавляются введенные в текстовое поля значения:
ContentValues cv = new ContentValues(); cv.put(DatabaseHelper.COLUMN_NAME, nameBox.getText().toString()); cv.put(DatabaseHelper.COLUMN_YEAR, Integer.parseInt(yearBox.getText().toString()));
При обновлении в метод update() передается название таблицы, объект ContentValues и критерий, по которому происходит обновление (в данном случае столбец id):
db.update(DatabaseHelper.TABLE, cv, DatabaseHelper.COLUMN_ID + " brush:java;">db.insert(DatabaseHelper.TABLE, null, cv);
Вместо этих методов, как в прошлой теме, можно использовать метод execSQL() с точным указанием выполняемого sql-выражения. В то же время методы delete/insert/update имеют преимущество — они возвращают id измененной записи, по которому мы можем узнать об успешности операции, или -1 в случае неудачной операции:
long result = db.insert(DatabaseHelper.TABLE, null, cv); if(result>0) < // действия >
После каждой операции выполняется метод goHome() , который возвращает на главную activity.
После этого нам надо исправить код MainActivity, чтобы она инициировала выполнение кода в UserActivity. Для этого изменим код activity_main.xml :
В данном случае была добавлена кнопка для вызова UserActivity.
И также изменим код класса MainActivity :
package com.example.sqliteapp; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.view.View; import android.widget.AdapterView; import android.widget.SimpleCursorAdapter; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.widget.ListView; public class MainActivity extends AppCompatActivity < ListView userList; DatabaseHelper databaseHelper; SQLiteDatabase db; Cursor userCursor; SimpleCursorAdapter userAdapter; @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); userList = findViewById(R.id.list); userList.setOnItemClickListener(new AdapterView.OnItemClickListener() < @Override public void onItemClick(AdapterViewparent, View view, int position, long id) < Intent intent = new Intent(getApplicationContext(), UserActivity.class); intent.putExtra("id", id); startActivity(intent); >>); databaseHelper = new DatabaseHelper(getApplicationContext()); > @Override public void onResume() < super.onResume(); // открываем подключение db = databaseHelper.getReadableDatabase(); //получаем данные из бд в виде курсора userCursor = db.rawQuery("select * from " + DatabaseHelper.TABLE, null); // определяем, какие столбцы из курсора будут выводиться в ListView String[] headers = new String[]; // создаем адаптер, передаем в него курсор userAdapter = new SimpleCursorAdapter(this, android.R.layout.two_line_list_item, userCursor, headers, new int[], 0); userList.setAdapter(userAdapter); > // по нажатию на кнопку запускаем UserActivity для добавления данных public void add(View view) < Intent intent = new Intent(this, UserActivity.class); startActivity(intent); >@Override public void onDestroy() < super.onDestroy(); // Закрываем подключение и курсор db.close(); userCursor.close(); >>
При нажатии на кнопку запускается UserActivity, при этом не передается никакого id, то есть в UserActivity id будет равен нулю, значит будет идти добавление данных:
Другую ситуацию представляет обработчик нажатия на элемент списка — при нажатии также будет запускаться UserActivity, но теперь будет передаваться id выбранной записи:
public void onItemClick(AdapterView parent, View view, int position, long id)
Запустим приложение и нажмем на кнопку, которая должен перенаправлять на UserActivity:
При нажатии в MainActivity на элемент списка этот элемент попадет на UserActivity, где его можно будет удалить или подредактировать: