Буквально самый простой способ исправить NullReferenceExeption имеет два пути. Если у вас есть GameObject, например, с прикрепленным скриптом и переменной с именем rb (rigidbody), эта переменная начнет пустую, когда вы начнете игру. Вот почему вы получаете NullReferenceExeption, потому что на компьютере нет данных, хранящихся в этой переменной.
В качестве примера я буду использовать переменную RigidBody. Мы можем добавить данные действительно легко на самом деле несколькими способами:
rb = GetComponent<Rigidbody>();
. Эта строка кода работает лучше всего под ваши функции Start()
или Awake()
. rb = AddComponent<RigidBody>();
Дальнейшие заметки: если вы хотите, чтобы единство добавлялось компонент для вашего объекта, и вы, возможно, забыли добавить его, вы можете ввести [RequireComponent(typeof(RigidBody))]
над объявлением класса (пробел ниже всех ваших приложений). Наслаждайтесь и получайте удовольствие от игр!
Обычный способ добиться желаемого результата - использовать команду pull.
Другим способом, который я предпочитаю в большинстве случаев, является копирование базы данных по коду на SD-карту:
try {
File sd = Environment.getExternalStorageDirectory();
if (sd.canWrite()) {
String currentDBPath = "/data/data/" + getPackageName() + "/databases/yourdatabasename";
String backupDBPath = "backupname.db";
File currentDB = new File(currentDBPath);
File backupDB = new File(sd, backupDBPath);
if (currentDB.exists()) {
FileChannel src = new FileInputStream(currentDB).getChannel();
FileChannel dst = new FileOutputStream(backupDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
}
}
} catch (Exception e) {
}
Не забудьте установить разрешение на запись в SD в вашем манифесте, как показано ниже.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
В качестве альтернативы вы можете использовать мою библиотеку Ultra Debugger . Это позволяет загружать базу данных в виде файла или редактировать значения непосредственно в браузере. Нет необходимости в корне, очень проста в использовании.
На основании ответа, данного Lam Vinh, вот простой командный файл, который работает для меня в моем первом поколении Nexus 7. Он предлагает пользователю ввести имя пакета, а затем имя базы данных (без расширения .sqlite) и помещает его в c: \ temp. Предполагается, что у вас установлен Android sdk в переменных среды.
@echo off
cd c:\temp\
set /p UserInputPackage= Enter the package name:
set /p UserInputDB= Enter the database name:
@echo on
adb shell "run-as %UserInputPackage% chmod 666 /data/data/%UserInputPackage%/databases/%UserInputDB%.sqlite"
adb pull /data/data/%UserInputPackage%/databases/%UserInputDB%.sqlite
@echo off
pause
Ниже приведено решение с фотографиями о том, как вы можете получить доступ к файловому системному файлу системы Android с Android 4. ssh от ubuntu 16.04
Я даю полное решение «сохранить» и «восстановить» базу данных приложения в / из внутреннего хранилища (а не на ПК с adb).
Я сделал два метода: один для сохранения и другие для восстановления базы данных. Используйте эти методы в конце onCreate () в MainActivity (один или другой, если вы хотите сохранить или восстановить базу данных).
сохранить базу данных во внутреннем хранилище:
void copyDatabase (){
try {
final String inFileName = "/data/data/<pakage.name>/databases/database.db";
final String outFileName = Environment.getExternalStorageDirectory() + "database_backup.db";
File dbFile = new File(inFileName);
FileInputStream fis = new FileInputStream(dbFile);
Log.d(TAG, "copyDatabase: outFile = " + outFileName);
// Open the empty db as the output stream
OutputStream output = new FileOutputStream(outFileName);
// Transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
// Close the streams
output.flush();
output.close();
fis.close();
}catch (Exception e){
Log.d(TAG, "copyDatabase: backup error");
}
}
восстановить базу данных из внутреннего хранилища:
void restoreDatabase (){
try {
final String inFileName = Environment.getExternalStorageDirectory() + "database_backup.db";
final String outFileName = "/data/data/<package.name>/databases/database.db";
File dbFile = new File(inFileName);
FileInputStream fis = new FileInputStream(dbFile);
Log.d(TAG, "copyDatabase: outFile = " + outFileName);
// Open the empty db as the output stream
OutputStream output = new FileOutputStream(outFileName);
// Transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
// Close the streams
output.flush();
output.close();
fis.close();
}catch (Exception e){
Log.d(TAG, "copyDatabase: backup error");
}
}
Если ваше устройство работает под управлением Android v4 или выше, вы можете вытащить данные приложения, включая его базу данных, без root, используя команду adb backup
, затем извлечь файл резервной копии и получить доступ к базе данных sqlite.
Первую резервную копию данных приложения на ПК через USB-кабель с помощью следующей команды замените app.package.name
на фактическое имя пакета приложения.
adb backup -f ~/data.ab -noapk app.package.name
Это предложит вам «разблокировать устройство и подтвердить операции резервного копирования ". Не предоставляйте пароль для резервного копирования, поэтому вы можете извлечь его позже. Нажмите кнопку «Восстановить мои данные» на своем устройстве. На экране отобразится имя пакета, который вы создаете резервную копию, а затем закройте его после успешного завершения.
Полученный файл data.ab
в вашей домашней папке содержит данные приложения в формате резервного копирования android. Чтобы извлечь его, используйте следующую команду:
dd if=data.ab bs=1 skip=24 | openssl zlib -d | tar -xvf -
Если выше закончилось с ошибкой openssl:Error: 'zlib' is an invalid command.
, попробуйте следующее.
dd if=data.ab bs=1 skip=24 | python -c "import zlib,sys;sys.stdout.write(zlib.decompress(sys.stdin.read()))" | tar -xvf -
В результате появится папка apps/app.package.name/
содержащие данные приложения, включая базу данных sqlite.
Для получения дополнительной информации вы можете проверить исходную запись в блоге .
> is it possible to pull in any way a database of an Android device without having to root it?
yes, если ваше приложение android создает копию файла базы данных, доступную всем.
android защищает личные данные приложений, чтобы они не были видны / доступны другим приложениям. база данных - это частные данные. ваше приложение может, конечно, прочитать файл базы данных, чтобы он мог копировать файл в какой-либо общедоступный видимый файл.
Если вы хотите, чтобы ваш файл базы данных
См. раздел DDMS> File explorer
, найдите ваш файл db из имени вашего пакета
, затем щелкните по извлечению файла от устройства (только укорененное устройство)
Всегда лучше, если все автоматизировано. Вот почему я написал простой скрипт python для копирования файла db с устройства с помощью ADB.
Работает только с отлаживаемыми приложениями, если устройство не укоренилось.
Запустите его как: python copyandroiddbfile.py
import sys
import subprocess
import re
#/
# Created by @nieldeokar on 25/05/2018.
#/
# 1. Python script which will copy database file of debuggable apps from the android device to your computer using ADB.
# 2. This script ask for PackageName and DatabaseName at runtime.
# 3. You can make it static by passing -d at as command line argument while running script and setting defaults in following way.
# 4. Edit script and change the values of varialbe packageName and dbName to debuggable app package name and database name then
# run script as : python Copydbfileandroid.py -d
useDefaults = False
def checkIfPackageInstalled(strSelectedDevice) :
packageName = 'com.nileshdeokar.healthapp.debug'
dbName = 'healthapp.db'
if not useDefaults :
print('Please enter package name : ')
packageName = raw_input()
packageString = 'package:'+packageName
try:
adbCheckIfPackageInstalledOutput = subprocess.check_output('adb -s ' + strSelectedDevice + ' shell pm list packages | grep -x '+ packageString, shell=True)
except subprocess.CalledProcessError as e:
print "Package not found"
return
if packageString.strip() == adbCheckIfPackageInstalledOutput.strip() :
if not useDefaults :
print('Please enter db name : ')
dbName = raw_input()
adbCopyDbString = 'adb -s '+strSelectedDevice + ' -d shell \"run-as '+packageName+' cat /data/data/'+packageName+'/databases/'+ dbName +'\" > '+dbName
try:
copyDbOp = subprocess.check_output(adbCopyDbString,shell=True)
except subprocess.CalledProcessError as e:
return
if "is not debuggable" in copyDbOp :
print packageString + 'is nto debuggable'
if copyDbOp.strip() == "":
print 'Successfully copied '+dbName + ' in current directory'
else :
print 'Package is not installed on the device'
defaultString = "-d"
if len(sys.argv[1:]) > 0 and sys.argv[1] == defaultString :
useDefaults = True
listDevicesOutput = subprocess.check_output("adb devices", shell=True)
listDevicesOutput = listDevicesOutput.replace("List of devices attached"," ").replace("\n","").replace("\t","").replace("\n\n","")
numberofDevices = len(re.findall(r'device+', listDevicesOutput))
connectedDevicesArray = listDevicesOutput.split("device")
del connectedDevicesArray[-1]
strSelectedDevice = ''
if(numberofDevices > 1) :
print('Please select the device : \n'),
for idx, device in enumerate(connectedDevicesArray):
print idx+1,device
selectedDevice = raw_input()
if selectedDevice.isdigit() :
intSelected = int(selectedDevice)
if 1 <= intSelected <= len(connectedDevicesArray) :
print 'Selected device is : ',connectedDevicesArray[intSelected-1]
checkIfPackageInstalled(connectedDevicesArray[intSelected-1])
else :
print 'Please select in range'
else :
print 'Not valid input'
elif numberofDevices == 1 :
checkIfPackageInstalled(connectedDevicesArray[0])
elif numberofDevices == 0 :
print("No device is attached")
Если вы пытаетесь сделать это на android 6, запросите разрешение и используйте код ответа на этот вопрос
if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_RC);
return;
}
Как только он будет предоставлен
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == STORAGE_PERMISSION_RC) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//permission granted start reading or writing database
} else {
Toast.makeText(this, "No permission to read external storage.", Toast.LENGTH_SHORT).show();
}
}
}
Для отлаживаемых приложений 1 на ненагруженных устройствах вы можете использовать следующую команду:
adb shell run-as package.name chmod 666 /data/data/package.name/databases/file
adb pull /data/data/package.name/databases/file
Пример:
adb shell run-as com.app chmod 666 /data/data/com.app/databases/data.db
adb pull /data/data/com.app/databases/data.db
Установить PATH adb для Enviroment Variables или использовать команду cd для платформы платформы Android sdk.
Пример:
cd /folder/android-sdk/platform-tools/
затем использовать команду выше
1 Обратите внимание, что большинство приложений в Play Store не отлаживаются, так как для этого необходимо установить флаг debuggable в манифесте.
Используя Android Studio 3.0 или более позднюю версию, вы можете вытащить базу данных (также разделяемую привилегию, каталог кеша и другие), если приложение запускается в режиме отладки на ненагруженном устройстве.
Чтобы вытащить базу данных с помощью студии Android, выполните следующие действия.
adb shell "run-as [package.name] chmod -R 777 /data/data/[package.name]/databases"
adb shell "mkdir -p /sdcard/tempDB"
adb shell "cp -r /data/data/[package.name]/databases/ /sdcard/tempDB/."
adb pull sdcard/tempDB/ .
adb shell "rm -r /sdcard/tempDB/*"
Если вы находитесь на Android 4.0 или более поздней версии, и вы находитесь на маке, то вот рубиновый скрипт, который сохранит ваше содержимое приложения на рабочем столе. Я бы предположил, что это также будет работать в Ubuntu, хотя я его не тестировал.
puts "enter your package name"
package_name = gets.chomp
puts "press the 'Back up my data' button on your device"
`adb backup -f ~/Desktop/data.ab -noapk #{package_name}`
puts "press enter once once the 'Backup finished' toast has appeared"
gets.chomp
puts "extracting..."
`dd if=data.ab bs=1 skip=24 | openssl zlib -d | tar -xvf -`
для запуска -> ruby your_ruby_file_name.rb
Этот сценарий является «счастливым путем», только, поэтому, пожалуйста, убедитесь, что ваше устройство подключено и что adb добавлен в ваш профиль.
Так как для меня ничего не работает. Я создаю небольшой скрипт Windows BATCH, основанный на других ответах, вместе взятых. Надеюсь, это поможет кому-то. Простое использование: backupDatabase & lt; PackageName> & lt; ApplicationName> [TargetDirectory]. Он использует метод резервного копирования Сергея и Android Backup Extractor .
@echo off
if [%1]==[] goto usage
if [%2]==[] goto usage
if NOT [%4]==[] goto usage
@echo Processing: preparations
set PACKAGE=%1
set APPLICATION_NAME=%2
set TARGET_DIR=%cd%
IF NOT "%~3"=="" set TARGET_DIR=%3
set PATH_ADB="c:\Program Files (x86)\Android\android-studio\sdk\platform-tools"
set PATH_ABE="c:\Programs\android-backup-extractor-20140630-bin"
set PATH_7Z="c:\Program Files\7-Zip"
@echo Processing: backup
%PATH_ADB%\adb.exe backup -f %TARGET_DIR%\%APPLICATION_NAME%\%APPLICATION_NAME%.ab -noapk %PACKAGE%
@echo Processing: unpack
java -jar %PATH_ABE%\abe.jar unpack %TARGET_DIR%\%APPLICATION_NAME%\%APPLICATION_NAME%.ab %TARGET_DIR%\%APPLICATION_NAME%\%APPLICATION_NAME%.ab.tar
@echo Processing: extract
cd %TARGET_DIR%\%APPLICATION_NAME%
%PATH_7Z%\7z.exe e %APPLICATION_NAME%.ab.tar "apps\%PACKAGE%\db\%APPLICATION_NAME%"
@echo Processing: cleaning
del %APPLICATION_NAME%.ab
del %APPLICATION_NAME%.ab.tar
goto :eof
:usage
@echo.Pull out SQLite database file from your android device.
@echo.Needs: - connected device
@echo. - device enable backup.
@echo. - application enable backup
@echo. - application in debug mode
@echo. - installed Android Backup Extractor
@echo. - installed command line TAR extractor (7z, ...)
@echo.Does NOT need: root device
@echo.
@echo.Uses: - ADB backup (set PATH_ADB)
@echo. - Android Backup Extractor (http://sourceforge.net/projects/adbextractor/) (set PATH_ABE)
@echo. - Extract TAR container, uses 7z (set PATH_7Z)
@echo.
@echo.Usage: backupDatabase ^<PackageName^> ^<ApplicationName^> [TargetDirectory]
@echo.Example: backupDatabase com.foo.example ExampleApp
@echo Example: backupDatabase com.foo.example ExampleApp workspace\AndroidProjects\Example
exit /B 1
Большинство ответов здесь намного сложнее, чем они должны быть. Если вы просто хотите скопировать базу данных своего приложения со своего телефона на свой компьютер, вам просто понадобится эта команда:
adb -d shell "run-as your.package.name cat databases/database.name" > target.sqlite
Все, что вам нужно для заполнения указанной выше команды, - это имя пакета вашего приложение, то, что вызывается из базы данных и, возможно, что / где вы хотите скопировать базу данных.
Обратите внимание, что эта конкретная команда будет работать только в том случае, если у вас есть только одно устройство подключен к вашему компьютеру. Параметр
-d
означает, что будет использоваться только подключенное устройство. Но есть и другие параметры, которые вы можете использовать вместо этого:
-e
будет нацелен на единственный запущенный эмулятор -s <serialnumber>
, который будет нацелен на устройство с определенным серийным номером. На корневом устройстве вы можете:
// check that db is there
>adb shell
# ls /data/data/app.package.name/databases
db_name.sqlite // a custom named db
# exit
// pull it
>adb pull /data/app.package.name/databases/db_name.sqlite
На Mac (требуется нулевой корень)
1. Go to platform-tools folder.
2) Run following command in terminal.
./adb -d shell "run-as your.package.name cat databases/database.sqlite" > database.sqlite
Он скопирует файл sqlite в папку инструментов платформы.
вы можете легко извлечь файл sqlite с вашего устройства (root не нужно)